@stacksjs/defaults 0.75.409 → 0.75.418

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.
@@ -733,3 +733,14 @@ not authenticate them. OAuth resource endpoints must explicitly use
733
733
  `authorizeOAuthDelegatedToken` with the exact resource, audience, workspace and
734
734
  required scopes. Ordinary refresh also refuses delegated refresh credentials;
735
735
  use the OAuth token endpoint and the registered client's protocol authentication.
736
+
737
+ ## Token-only recovery endpoints
738
+
739
+ For high-entropy reset credentials, `mintPasswordResetToken()` returns `{ token, digest }`.
740
+ Store the digest in `password_resets.token`, never the plaintext.
741
+ `consumePasswordResetToken(token, async claim => { ... })` locks the owner and token,
742
+ checks the stored expiry and consumes it in the same transaction as callback writes.
743
+ `claim` is `{ userId, email, hasExplicitExpiry }`; result is `{ consumed: false }` or
744
+ `{ consumed: true, value }`. Failures roll back the credential and account changes.
745
+ Use database work only in the callback, and send notifications after commit.
746
+ The existing `passwordResets(email)` flow supports email-addressed bcrypt tokens.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-browser-extension
3
- description: Use when scaffolding, building, packaging or preparing store submission for a native Stacks MV3 browser extension. Covers @stacksjs/browser-extension and Chrome/Firefox/Safari target boundaries.
3
+ description: Use when scaffolding, building, packaging or preparing store submission for a native Stacks MV3 browser extension, or shipping its rules and content scripts to a WKWebView app. Covers @stacksjs/browser-extension and Chrome/Firefox/Safari/WebKit target boundaries.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -26,6 +26,30 @@ and Firefox. Safari additionally uses container-app scaffolding, resource sync
26
26
  and xcodebuild on a suitable macOS toolchain. Target limitations are explicit;
27
27
  do not substitute one browser's package for another.
28
28
 
29
+ ## WebKit target
30
+
31
+ `buddy extension:build --target webkit` writes `dist-webkit/` for apps that
32
+ embed WKWebView and have no extension runtime: the DNR rulesets (plus
33
+ `webkit.dynamicRules` and `webkit.cosmetic` sources) as WebKit content-blocker
34
+ lists in `lists/<id>.json`, every content script as a standalone
35
+ `WKUserScript` in `scripts/<id>.js`, and a `manifest.json` describing both.
36
+ It never changes the Chrome, Firefox or Safari outputs.
37
+
38
+ The converter is `src/webkit.ts` (`buildWebKitLists`, `convertDnrRule`,
39
+ `urlFilterToWebKitRegex`, `regexFilterToWebKit`), importable at runtime as
40
+ `@stacksjs/browser-extension/webkit`. Lists split under `maxRulesPerList`
41
+ (default 50,000; WebKit refuses more than 150,000) with a stable id and a
42
+ content-hash version. What WebKit cannot express (redirect, modifyHeaders,
43
+ method/tab/header conditions, `excludedRequestDomains`, lookaround regexes) is
44
+ counted in `report.unsupported`; looser or narrower matches in
45
+ `report.approximated`. Neither is dropped silently, so read the report.
46
+
47
+ Isolated-world scripts that call `chrome.runtime` / `chrome.storage` are
48
+ bridged to `window.webkit.messageHandlers.<name>`; the host app implements
49
+ that handler. The mapping table, ordering rules and message contract are in
50
+ [WEBKIT.md](WEBKIT.md). Ship `dist-webkit` to apps through a library package's
51
+ `assets` (see `stacks-build`).
52
+
29
53
  ## Store preparation and publication
30
54
 
31
55
  The package includes publish plans and adapters for Chrome Web Store, Firefox
@@ -37,4 +61,5 @@ credentials into the extension's public files.
37
61
  Verify generated manifests, CSP, permissions, scripts, packaged file lists,
38
62
  and target-specific tests. Device and store outcomes need their own evidence.
39
63
  Source: core/browser-extension/src/{config,manifest,build,package,scaffold,
40
- publish-plan,safari}.ts and store adapters. Tests cover these same boundaries.
64
+ publish-plan,safari,webkit,webkit-scripts,webkit-build}.ts and store adapters.
65
+ Tests cover these same boundaries.
@@ -0,0 +1,139 @@
1
+ # The WebKit target
2
+
3
+ `buddy extension:build --target webkit` (or `targets: [..., 'webkit']`) builds
4
+ an extension for apps that embed WKWebView. Source: `src/webkit.ts` (the
5
+ converter), `src/webkit-scripts.ts` (user scripts and the bridge),
6
+ `src/webkit-build.ts` (the build). Tests: `tests/webkit.test.ts`,
7
+ `tests/webkit-build.test.ts`.
8
+
9
+ ## Config
10
+
11
+ ```ts
12
+ defineExtension({
13
+ rules: [{ id: 'static', source: 'src/rules/static.ts' }], // each becomes a list group
14
+ content: [/* ... */], // each becomes a user script
15
+ webkit: {
16
+ maxRulesPerList: 50_000, // WebKit's own cap is 150,000
17
+ dynamicRules: [{ id: 'dynamic', source: 'src/rules/webkit.ts#dynamicRules' }], // path#export
18
+ cosmetic: [
19
+ { id: 'cosmetic', source: 'src/rules/webkit.ts#cosmetic' },
20
+ { id: 'cosmetic-consent', source: 'src/rules/webkit.ts#consent', enabled: false },
21
+ ],
22
+ selectorsPerRule: 100,
23
+ messageHandler: 'my-extension', // default: the name as a slug
24
+ excludeScripts: [], // by output name, e.g. 'content'
25
+ },
26
+ })
27
+ ```
28
+
29
+ A source is a module path, or `path#name` for one of its exports (a function
30
+ is called). A `dynamicRules` source returns DNR rules (the defaults the extension would
31
+ install with `updateDynamicRules`). A `cosmetic` source returns
32
+ `WebKitCosmeticRule[]`: `{ selector: string | string[], domains?, excludedDomains? }`.
33
+
34
+ ## Output
35
+
36
+ ```
37
+ dist-webkit/
38
+ manifest.json format 'stacks-webkit', formatVersion 1
39
+ lists/<id>.json the JSON array for WKContentRuleListStore.compileContentRuleList
40
+ scripts/<id>.js WKUserScript source
41
+ ```
42
+
43
+ `manifest.json` lists `{ id, version, group, kind, enabled, ruleCount, file }`
44
+ per list, `{ id, file, matches, excludeMatches, runAt, allFrames,
45
+ matchAboutBlank, world, bridged, apis, unsupportedApis }` per script, the
46
+ bridge's `{ messageHandler, version }`, and the conversion `report`.
47
+
48
+ Compile each list under its `id` and recompile only when `version` (a SHA-256
49
+ prefix of the rules) changes. `enabled: false` mirrors a ruleset the extension
50
+ leaves off by default. `runAt` is `document-start` or `document-end` (DNR's
51
+ `document_idle` has no WebKit counterpart). `world: 'page'` is
52
+ `WKContentWorld.page`; `isolated` is a content world of the app's own.
53
+ `matches` are extension match patterns for the app to test URLs against.
54
+
55
+ ## DNR to WebKit
56
+
57
+ | DNR | WebKit |
58
+ |---|---|
59
+ | `urlFilter` `\|\|host^` | `^[a-z][a-z0-9+.-]*://([^/:]*\.)?host[:/]` |
60
+ | `urlFilter` `^` / trailing `^` / `*` / `\|` | `[^a-zA-Z0-9_.%-]` / `([^…].*)?$` / `.*` / `^`, `$` |
61
+ | `regexFilter` | passed through; `\d`, `\w`, `(?:)`, `{n,m}` rewritten; alternation expanded into one rule per alternative (64 max) |
62
+ | `requestDomains` | one host-anchored `url-filter` per domain |
63
+ | `initiatorDomains` / `excludedInitiatorDomains` | `if-domain` / `unless-domain` (`*domain`) |
64
+ | `domainType` | `load-type` |
65
+ | `isUrlFilterCaseSensitive` | `url-filter-is-case-sensitive` |
66
+ | `resourceTypes` | `resource-type`; `main_frame` is `document` + `load-context: top-frame` plus a `popup` rule, `sub_frame` is `document` + `load-context: child-frame`; `xmlhttprequest` is `fetch`, `csp_report` is `ping`, `object` is `other` |
67
+ | `block` / `allow` / `upgradeScheme` | `block` / `ignore-previous-rules` / `make-https` |
68
+ | `allowAllRequests` | `ignore-previous-rules` on `.*`, `if-domain` the page's domain |
69
+
70
+ DNR leaves top-level documents out when a rule names no resource types; WebKit
71
+ includes them, so those rules spell the frames out. Unsupported, and counted
72
+ in `report.unsupported`: `redirect`, `modifyHeaders`, request-method, tab and
73
+ response-header conditions, `excludedRequestDomains`, regex lookaround or
74
+ back-references, exclusions under an included domain, non-ASCII filters, and
75
+ cosmetic selectors with procedural (adblock-only) pseudo-classes or broken
76
+ syntax.
77
+
78
+ ## Ordering and splitting
79
+
80
+ `ignore-previous-rules` only lifts rules before it in the same list, and each
81
+ list compiles alone while DNR evaluates every ruleset together. So each list is
82
+ sorted by DNR priority, then DNR precedence (make-https, block,
83
+ allowAllRequests, allow), and every network list repeats the exceptions of all
84
+ enabled groups (a disabled group adds its own to its own lists). Exceptions
85
+ count toward `maxRulesPerList`. Cosmetic lists receive no network exceptions:
86
+ a DNR `allow` never unhides elements in the extension either. To allowlist a
87
+ site in the app, leave its lists off that page's content controller or
88
+ recompile with a page-wide `ignore-previous-rules`.
89
+
90
+ Requires a current WebKit (`load-context` and the `fetch`/`websocket`/`other`
91
+ resource types).
92
+
93
+ ## The bridge (contract v1)
94
+
95
+ Isolated-world scripts that touch `chrome.*` are wrapped so `chrome` and
96
+ `browser` are the bridge; the page gets no global. Supported: `runtime.sendMessage`,
97
+ `runtime.onMessage`, `runtime.id`, `runtime.lastError`,
98
+ `storage.{local,sync,session}.{get,set,remove,clear,onChanged}` and
99
+ `storage.onChanged`. Anything else is listed in the script's
100
+ `unsupportedApis` and fails at runtime.
101
+
102
+ Register the handler with `WKScriptMessageHandlerWithReply` so `postMessage`
103
+ resolves to your reply. Page to app:
104
+
105
+ | `body.api` | `body.payload` | reply |
106
+ |---|---|---|
107
+ | `runtime.sendMessage` | `{ message }` | the response, or null |
108
+ | `storage.get` | `{ area, keys: null \| string \| string[] \| object }` | the stored items (the bridge fills in object defaults) |
109
+ | `storage.set` | `{ area, items }` | null |
110
+ | `storage.remove` | `{ area, keys: string[] }` | null |
111
+ | `storage.clear` | `{ area }` | null |
112
+
113
+ Every body has `v: 1`. A rejected reply rejects the call (callback callers see
114
+ `chrome.runtime.lastError`). App to page, evaluated in the script's content
115
+ world with `callAsyncJavaScript`:
116
+
117
+ ```js
118
+ __stacksWebKit[handler].dispatch({ type: 'runtime.message', message, sender }) // resolves to the first response
119
+ __stacksWebKit[handler].dispatch({ type: 'storage.changed', area, changes }) // { key: { oldValue, newValue } }
120
+ ```
121
+
122
+ ## Publishing to apps
123
+
124
+ Ship `dist-webkit` in a library package and give it a small typed reader in
125
+ `resources/functions`:
126
+
127
+ ```ts
128
+ // config/library.ts
129
+ packages: [{
130
+ name: 'my-blocker',
131
+ include: ['webkit.ts'],
132
+ registry: 'npm',
133
+ prebuild: 'buddy extension:build --target webkit',
134
+ assets: { webkit: 'dist-webkit' }, // lands in dist/webkit/, exported as my-blocker/webkit/*
135
+ }]
136
+ ```
137
+
138
+ The reader resolves `new URL('./webkit/manifest.json', import.meta.url)`, which
139
+ is `dist/webkit/manifest.json` once built.
@@ -157,6 +157,19 @@ npm sets `registry: 'npm'`, which publishes with `pantry publish --npm`, or with
157
157
  Each package publishes its own `readme` (a project-relative Markdown file) as
158
158
  README.md, or a short one the build writes from its `description`.
159
159
 
160
+ A package build compiles TypeScript and nothing else, so generated data (JSON,
161
+ scripts, lists) ships through `assets`: `{ 'path/in/package': 'project/source' }`,
162
+ copied into `dist/` after the compile. A path with an extension is a file and
163
+ gets an exact export; any other path is a directory whose contents are exported
164
+ as `<name>/<path>/*` (never `<name>/<path>` itself, which would shadow a module
165
+ of the same name). Code reads them with `new URL('./<path>/…', import.meta.url)`.
166
+ `prebuild` is a shell command run in the project root before the package
167
+ builds, so the assets are regenerated rather than shipped stale:
168
+
169
+ ```ts
170
+ { name: 'my-blocker', include: ['webkit.ts'], prebuild: 'buddy extension:build --target webkit', assets: { webkit: 'dist-webkit' } }
171
+ ```
172
+
160
173
  ### Things that will stop a build, on purpose
161
174
 
162
175
  - **A package that matches no files.** Nearly always a typo'd glob, and the
@@ -164,6 +177,8 @@ README.md, or a short one the build writes from its `description`.
164
177
  packages instead, so an app that never filled in `resources/` is not blocked.
165
178
  - **Two packages that resolve to the same directory** (`@acme/ui` and
166
179
  `@other/ui` both unscope to `ui`). Give one an explicit `dir`.
180
+ - **A missing asset, or a failed `prebuild`.** Publishing the previous output
181
+ of a step that just failed is how a stale package ships.
167
182
  - **stx ambient globals in a `functions` package.** `state`, `useDark` and the
168
183
  rest are injected into an stx page entry and exported by nothing, so a
169
184
  bundled copy compiles and then throws `ReferenceError` on the consumer's
@@ -137,7 +137,9 @@ hostname. LAN HTTPS comes from a certificate authority on the box itself (rpx `l
137
137
  Let's Encrypt. To publish: routable address, ports 80 and 443 forwarded, a site with a domain, and
138
138
  `ssh.publicIp` set. `TS_CLOUD_SSH_PUBLISH_DNS=1` forces publishing on, `0` forces it off.
139
139
 
140
- **Shared boxes.** Both targets support `cloud.attachTo: '<owner slug>'`. An attached project skips
140
+ **Shared boxes.** Set `tsCloud.cloud.attachTo` to
141
+ `process.env.CLOUD_ATTACH_TO || undefined` in the named `tsCloud` export and
142
+ supply the owner's slug through the protected deploy environment. An attached project skips
141
143
  provisioning and deploys only its own sites. Each project owns `/etc/rpx/sites.d/<slug>.json` and
142
144
  replaces it wholesale, so `project.slug` must be unique on the box, and the config must declare
143
145
  every domain that fragment currently serves or the deploy stops.
@@ -257,10 +259,13 @@ export const tsCloud: TsCloudConfig = {
257
259
  mode: 'server',
258
260
  }
259
261
 
260
- const config: CloudConfig = { tenants: ['attached-project'] }
262
+ const config: CloudConfig = {}
261
263
  export default config
262
264
  ~~~
263
265
 
266
+ Keep the tenant roster in `STACKS_CLOUD_TENANTS` or the private sources described
267
+ in `stacks-env`. A declared `tenants` array remains available for private forks.
268
+
264
269
  Extend the named tsCloud object using its typed sites, environments and
265
270
  infrastructure options. The default Stacks wrapper holds surrounding settings
266
271
  such as tenant isolation. Provider configuration does not belong at an invented
@@ -375,3 +375,11 @@ not jurisdiction-specific compensation or overtime decisions.
375
375
  localTimeSpan(date, start, end, ...zones) converts a clock interval, including
376
376
  next-day ends, to actual instants for cross-site/overnight overlap checks.
377
377
  Equal endpoints and non-positive DST-normalized intervals are rejected.
378
+
379
+ ## Conflicts across location clocks
380
+
381
+ Convert each appointment using `localTimeSpan(date, start, end, ...zones)` and compare
382
+ with `timeSpansOverlap(first, second)`. Intervals are half-open, so adjacent sessions
383
+ do not conflict. Query neighboring local dates before comparing: simultaneous
384
+ appointments can belong to different calendar dates in different zones. Never
385
+ compare local clock strings from separate locations directly.
@@ -227,8 +227,9 @@ buddy cloud:cleanup # clean retained resources
227
227
  - On Hetzner and SSH, a project's `/etc/rpx/sites.d/<slug>.json` is replaced wholesale, so
228
228
  `project.slug` must be unique on a shared box and the config must declare every domain that
229
229
  fragment serves
230
- - `.env.<environment>` is decrypted at deploy time and shipped as every site's `.env`, so declare
231
- `tenants` in `config/cloud.ts` on a shared box to strip other tenants' keys
230
+ - `.env.<environment>` is decrypted at deploy time and shipped as every site's `.env`. Supply the
231
+ shared-box roster through `STACKS_CLOUD_TENANTS` or private tenant files so other tenants' keys
232
+ are stripped. See `stacks-env` for the private-source precedence.
232
233
  - A failover replica bucket (`infrastructure.storage.<name>.failover`) lives outside the stack, so
233
234
  `buddy cloud:remove` leaves it, and its data, behind on purpose
234
235
  - For infrastructure details, see the `stacks-cloud` skill
@@ -285,26 +285,28 @@ When several projects share one server - one owns it, the rest attach with
285
285
  They leak anyway: a tenant's secrets get pasted into the owner's env file under
286
286
  a `TENANT_` prefix while debugging a deploy, and stay. That is not just untidy.
287
287
  `buddy deploy` ships the whole env file as **every** site's `.env` (ts-cloud
288
- treats `site.env` as the complete file), so a stray `BUGHQ_STRIPE_SECRET_KEY` in
288
+ treats `site.env` as the complete file), so a stray `OTHERAPP_API_KEY` in
289
289
  the owner's file lands on disk in an unrelated site.
290
290
 
291
- Declare who is attached, in `config/cloud.ts`'s default export:
291
+ Keep the tenant roster private. `buddy deploy` and `buddy env:check` merge:
292
292
 
293
- ```typescript
294
- const config: CloudConfig = {
295
- tenants: ['bughq', 'analyticshq'],
296
- }
297
- ```
293
+ - `STACKS_CLOUD_TENANTS`, a comma or whitespace separated list of slugs. CI
294
+ supplies this through a protected secret, without printing it.
295
+ - `$STACKS_PRIVATE_DIR/tenants.json`, `~/.config/stacks/tenants.json`, and the
296
+ gitignored `storage/cloud/tenants.json`. Each accepts a JSON array of slugs
297
+ or an object with a `tenants` array.
298
+ - A `tenants` array in `config/cloud.ts`'s default wrapper, retained for private
299
+ forks. Public repositories use the private sources above.
298
300
 
299
301
  With that:
300
302
 
301
303
  - `buddy deploy` drops those keys before shipping, and logs what it dropped
302
304
  - `buddy env:check` lists them per tenant so they can be deleted at source
303
305
 
304
- Prefixes are **never** inferred. With no `tenants` declared nothing is treated
306
+ Prefixes are **never** inferred. With no tenant roster loaded nothing is treated
305
307
  as foreign, because `STRIPE_`, `AWS_` and `MEILISEARCH_` are indistinguishable
306
308
  from a slug prefix by shape alone. Slug punctuation is ignored, so
307
- `analytics-hq` and `analytics_hq` both match `ANALYTICSHQ_`.
309
+ `other-app` and `other_app` both match `OTHERAPP_`.
308
310
 
309
311
  The API is `partitionTenantEnv(values, { self, tenants })` from
310
312
  `@stacksjs/env`, plus `stripForeignTenantEnv` and `foreignTenantKeys`.
@@ -330,8 +332,8 @@ calls or raw client-side `fetch`.
330
332
 
331
333
  ## Gotchas
332
334
  - **A tenant's keys in your env file get shipped everywhere.** `buddy deploy`
333
- sends the entire env file as each site's `.env`. Declare `tenants` in
334
- `config/cloud.ts` so they are stripped, then delete them at source
335
+ sends the entire env file as each site's `.env`. Supply the private tenant
336
+ roster so foreign keys are stripped, then delete them at source
335
337
  - Bun natively loads `.env` - no dotenv package needed
336
338
  - The `env` proxy auto-coerces strings to booleans/numbers
337
339
  - `.env` should never be committed - use `.env.example` as template
@@ -35,3 +35,11 @@ STX uses img and the asset pipeline, not a framework-specific React image wrappe
35
35
  Test no-upscale behavior, requested formats, source authorization, negotiated
36
36
  responses, signed access and storage publication. Source: core/image/src/index.ts
37
37
  and its generation modules. Evidence: image.test.ts and generate.test.ts.
38
+
39
+ ## Private uploads
40
+
41
+ Use `sanitizeImageUpload(bytes, { maxBytes?, maxPixels? })` before storing a private
42
+ JPEG, PNG or WebP. It bounds bytes and pixels, applies camera orientation, strips
43
+ source metadata by encoding only pixels, and returns canonical bytes/dimensions.
44
+ The default caps are 12 MiB and 40 million pixels. Authorization, referencing and
45
+ object retention remain application policy.
@@ -18,12 +18,12 @@ Browser runtime bindings are documented separately in `stacks-auto-imports`.
18
18
  | `@stacksjs/api` | [`stacks-api`](../stacks-api/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/api/src/index.ts) | 9 |
19
19
  | `@stacksjs/arrays` | [`stacks-arrays`](../stacks-arrays/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/arrays/src/index.ts) | 6 |
20
20
  | `@stacksjs/audio` | [`stacks-audio`](../stacks-audio/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/audio/src/index.ts) | 3 |
21
- | `@stacksjs/auth` | [`stacks-auth`](../stacks-auth/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/index.ts) | 124 |
21
+ | `@stacksjs/auth` | [`stacks-auth`](../stacks-auth/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/index.ts) | 125 |
22
22
  | `@stacksjs/browser` | [`stacks-browser`](../stacks-browser/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser/src/index.ts) | 8 |
23
- | `@stacksjs/browser-extension` | [`stacks-browser-extension`](../stacks-browser-extension/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/index.ts) | 7 |
24
- | `@stacksjs/buddy` | [`stacks-buddy`](../stacks-buddy/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/buddy/src/index.ts) | 176 |
23
+ | `@stacksjs/browser-extension` | [`stacks-browser-extension`](../stacks-browser-extension/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/index.ts) | 9 |
24
+ | `@stacksjs/buddy` | [`stacks-buddy`](../stacks-buddy/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/buddy/src/index.ts) | 177 |
25
25
  | `@stacksjs/build` | [`stacks-build`](../stacks-build/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/build/src/index.ts) | 5 |
26
- | `@stacksjs/cache` | [`stacks-cache`](../stacks-cache/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/cache/src/index.ts) | 18 |
26
+ | `@stacksjs/cache` | [`stacks-cache`](../stacks-cache/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/cache/src/index.ts) | 23 |
27
27
  | `@stacksjs/calendar-api` | [`stacks-calendar`](../stacks-calendar/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/calendar-api/src/index.ts) | 2 |
28
28
  | `@stacksjs/charts` | [`stacks-charts`](../stacks-charts/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/charts/src/index.ts) | 3 |
29
29
  | `@stacksjs/chat` | [`stacks-chat`](../stacks-chat/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/chat/src/index.ts) | 5 |
@@ -36,7 +36,7 @@ Browser runtime bindings are documented separately in `stacks-auto-imports`.
36
36
  | `@stacksjs/config` | [`stacks-config`](../stacks-config/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/config/src/index.ts) | 16 |
37
37
  | `@stacksjs/cron` | [`stacks-cron`](../stacks-cron/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/cron/src/index.ts) | 6 |
38
38
  | `@stacksjs/database` | [`stacks-database`](../stacks-database/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/database/src/index.ts) | 135 |
39
- | `@stacksjs/datetime` | [`stacks-datetime`](../stacks-datetime/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/datetime/src/index.ts) | 13 |
39
+ | `@stacksjs/datetime` | [`stacks-datetime`](../stacks-datetime/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/datetime/src/index.ts) | 14 |
40
40
  | `@stacksjs/defaults` | [`stacks-build`](../stacks-build/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/defaults/package.json) | 2 |
41
41
  | `@stacksjs/deploy` | [`stacks-deploy`](../stacks-deploy/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/deploy/package.json) | 1 |
42
42
  | `@stacksjs/desktop-build` | [`stacks-desktop`](../stacks-desktop/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/desktop/src/index.ts) | 15 |
@@ -57,7 +57,7 @@ Browser runtime bindings are documented separately in `stacks-auto-imports`.
57
57
  | `@stacksjs/health` | [`stacks-health`](../stacks-health/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/health/src/index.ts) | 2 |
58
58
  | `@stacksjs/http` | [`stacks-http`](../stacks-http/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/http/src/index.ts) | 2 |
59
59
  | `@stacksjs/i18n` | [`stacks-i18n`](../stacks-i18n/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/i18n/src/index.ts) | 4 |
60
- | `@stacksjs/image` | [`stacks-image`](../stacks-image/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/image/src/index.ts) | 2 |
60
+ | `@stacksjs/image` | [`stacks-image`](../stacks-image/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/image/src/index.ts) | 3 |
61
61
  | `@stacksjs/lint` | [`stacks-lint`](../stacks-lint/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/lint/src/index.ts) | 3 |
62
62
  | `@stacksjs/logging` | [`stacks-logging`](../stacks-logging/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/logging/src/index.ts) | 14 |
63
63
  | `@stacksjs/mobile` | [`stacks-mobile`](../stacks-mobile/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/index.ts) | 23 |
@@ -86,9 +86,9 @@ Browser runtime bindings are documented separately in `stacks-auto-imports`.
86
86
  | `@stacksjs/slug` | [`stacks-slug`](../stacks-slug/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/slug/src/index.ts) | 5 |
87
87
  | `@stacksjs/sms` | [`stacks-sms`](../stacks-sms/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/sms/src/index.ts) | 5 |
88
88
  | `@stacksjs/socials` | [`stacks-socials`](../stacks-socials/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/socials/src/index.ts) | 17 |
89
- | `@stacksjs/storage` | [`stacks-storage`](../stacks-storage/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/index.ts) | 42 |
89
+ | `@stacksjs/storage` | [`stacks-storage`](../stacks-storage/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/index.ts) | 47 |
90
90
  | `@stacksjs/strings` | [`stacks-strings`](../stacks-strings/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/strings/src/index.ts) | 7 |
91
- | `@stacksjs/testing` | [`stacks-testing`](../stacks-testing/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/index.ts) | 20 |
91
+ | `@stacksjs/testing` | [`stacks-testing`](../stacks-testing/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/index.ts) | 21 |
92
92
  | `@stacksjs/tinker` | [`stacks-repl`](../stacks-repl/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/tinker/src/index.ts) | 1 |
93
93
  | `@stacksjs/tunnel` | [`stacks-tunnel`](../stacks-tunnel/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/tunnel/src/index.ts) | 1 |
94
94
  | `@stacksjs/types` | [`stacks-types`](../stacks-types/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/types/src/index.ts) | 2 |
@@ -185,9 +185,9 @@ Guidance: [`stacks-auth`](../stacks-auth/SKILL.md). Source: [storage/framework/c
185
185
 
186
186
  Declared runtime exports: `DEFAULT_ROLE_PACKS`, `createBqbRbacStore`, `generateTOTP`, `generateTOTPSecret`, `requestImpersonation`, `seedDefaultRoles`, `totpKeyUri`, `verifyTOTP`.
187
187
 
188
- Local source modules: [src/authentication.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/authentication.ts), [src/authenticator.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/authenticator.ts), [src/authorizable.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/authorizable.ts), [src/browser-session.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/browser-session.ts), [src/client.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/client.ts), [src/cookie-auth.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/cookie-auth.ts), [src/credential-user.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/credential-user.ts), [src/email-verification.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/email-verification.ts), [src/gate.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/gate.ts), [src/impersonation-auth.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/impersonation-auth.ts), [src/impersonation-store.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/impersonation-store.ts), [src/impersonation.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/impersonation.ts), [src/magic-link.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/magic-link.ts), [src/middleware.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/middleware.ts), [src/oauth-authorization-codes.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-authorization-codes.ts), [src/oauth-authorization-endpoint.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-authorization-endpoint.ts), [src/oauth-authorization-requests.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-authorization-requests.ts), [src/oauth-authorization-response.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-authorization-response.ts), [src/oauth-authorization.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-authorization.ts), [src/oauth-browser-session.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-browser-session.ts), [src/oauth-client-registration.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-client-registration.ts), [src/oauth-consent.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-consent.ts), [src/oauth-delegated-access.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-delegated-access.ts), [src/oauth-dynamic-registration.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-dynamic-registration.ts), [src/oauth-grants.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-grants.ts), [src/oauth-introspection.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-introspection.ts), [src/oauth-metadata.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-metadata.ts), [src/oauth-pkce.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-pkce.ts), [src/oauth-protected-resource.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-protected-resource.ts), [src/oauth-provider.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-provider.ts), [src/oauth-pruning.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-pruning.ts), [src/oauth-revocation.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-revocation.ts), [src/oauth-server.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-server.ts), [src/oauth-token-endpoint.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-token-endpoint.ts), [src/oauth-token-exchange.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-token-exchange.ts), [src/oauth-token-request.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-token-request.ts), [src/oauth-token-response.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-token-response.ts), [src/page-gate.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/page-gate.ts), [src/passkey.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/passkey.ts), [src/passkeys.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/passkeys.ts), [src/password/reset.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/password/reset.ts), [src/permissions.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/permissions.ts), [src/policy.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/policy.ts), [src/rate-limiter.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/rate-limiter.ts), [src/rbac-seed.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/rbac-seed.ts), [src/rbac-store-bqb.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/rbac-store-bqb.ts), [src/rbac.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/rbac.ts), [src/referrals.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/referrals.ts), [src/register.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/register.ts), [src/request-token.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/request-token.ts), [src/session-auth.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/session-auth.ts), [src/session-handoff.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/session-handoff.ts), [src/socials.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/socials.ts), [src/team.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/team.ts), [src/tokens.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/tokens.ts), [src/two-factor.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/two-factor.ts), [src/user.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/user.ts).
188
+ Local source modules: [src/authentication.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/authentication.ts), [src/authenticator.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/authenticator.ts), [src/authorizable.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/authorizable.ts), [src/browser-session.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/browser-session.ts), [src/client.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/client.ts), [src/cookie-auth.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/cookie-auth.ts), [src/credential-user.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/credential-user.ts), [src/email-verification.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/email-verification.ts), [src/gate.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/gate.ts), [src/impersonation-auth.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/impersonation-auth.ts), [src/impersonation-store.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/impersonation-store.ts), [src/impersonation.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/impersonation.ts), [src/magic-link.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/magic-link.ts), [src/middleware.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/middleware.ts), [src/oauth-authorization-codes.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-authorization-codes.ts), [src/oauth-authorization-endpoint.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-authorization-endpoint.ts), [src/oauth-authorization-requests.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-authorization-requests.ts), [src/oauth-authorization-response.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-authorization-response.ts), [src/oauth-authorization.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-authorization.ts), [src/oauth-browser-session.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-browser-session.ts), [src/oauth-client-registration.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-client-registration.ts), [src/oauth-consent.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-consent.ts), [src/oauth-delegated-access.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-delegated-access.ts), [src/oauth-dynamic-registration.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-dynamic-registration.ts), [src/oauth-grants.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-grants.ts), [src/oauth-introspection.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-introspection.ts), [src/oauth-metadata.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-metadata.ts), [src/oauth-pkce.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-pkce.ts), [src/oauth-protected-resource.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-protected-resource.ts), [src/oauth-provider.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-provider.ts), [src/oauth-pruning.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-pruning.ts), [src/oauth-revocation.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-revocation.ts), [src/oauth-server.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-server.ts), [src/oauth-token-endpoint.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-token-endpoint.ts), [src/oauth-token-exchange.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-token-exchange.ts), [src/oauth-token-request.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-token-request.ts), [src/oauth-token-response.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/oauth-token-response.ts), [src/page-gate.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/page-gate.ts), [src/passkey.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/passkey.ts), [src/passkeys.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/passkeys.ts), [src/password/reset-token.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/password/reset-token.ts), [src/password/reset.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/password/reset.ts), [src/permissions.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/permissions.ts), [src/policy.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/policy.ts), [src/rate-limiter.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/rate-limiter.ts), [src/rbac-seed.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/rbac-seed.ts), [src/rbac-store-bqb.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/rbac-store-bqb.ts), [src/rbac.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/rbac.ts), [src/referrals.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/referrals.ts), [src/register.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/register.ts), [src/request-token.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/request-token.ts), [src/session-auth.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/session-auth.ts), [src/session-handoff.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/session-handoff.ts), [src/socials.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/socials.ts), [src/team.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/team.ts), [src/tokens.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/tokens.ts), [src/two-factor.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/two-factor.ts), [src/user.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/user.ts).
189
189
 
190
- Evidence directory: [124 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
190
+ Evidence directory: [125 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
191
191
 
192
192
  ### @stacksjs/browser
193
193
 
@@ -205,9 +205,9 @@ Guidance: [`stacks-browser-extension`](../stacks-browser-extension/SKILL.md). So
205
205
 
206
206
  Read the entrypoint and package export map for re-exported or type-only surfaces.
207
207
 
208
- Local source modules: [src/app-store-connect.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/app-store-connect.ts), [src/app-store-submission.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/app-store-submission.ts), [src/build.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/build.ts), [src/chrome-web-store.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/chrome-web-store.ts), [src/config.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/config.ts), [src/firefox-addons.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/firefox-addons.ts), [src/firefox-previews.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/firefox-previews.ts), [src/manifest.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/manifest.ts), [src/package.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/package.ts), [src/publish-plan.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/publish-plan.ts), [src/safari.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/safari.ts), [src/sanitize.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/sanitize.ts), [src/scaffold.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/scaffold.ts), [src/types.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/types.ts).
208
+ Local source modules: [src/app-store-connect.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/app-store-connect.ts), [src/app-store-submission.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/app-store-submission.ts), [src/build.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/build.ts), [src/chrome-web-store.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/chrome-web-store.ts), [src/config.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/config.ts), [src/firefox-addons.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/firefox-addons.ts), [src/firefox-previews.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/firefox-previews.ts), [src/manifest.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/manifest.ts), [src/package.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/package.ts), [src/publish-plan.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/publish-plan.ts), [src/safari.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/safari.ts), [src/sanitize.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/sanitize.ts), [src/scaffold.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/scaffold.ts), [src/types.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/types.ts), [src/webkit-build.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/webkit-build.ts), [src/webkit-scripts.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/webkit-scripts.ts), [src/webkit.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/webkit.ts).
209
209
 
210
- Evidence directory: [7 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
210
+ Evidence directory: [9 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
211
211
 
212
212
  ### @stacksjs/buddy
213
213
 
@@ -217,7 +217,7 @@ Read the entrypoint and package export map for re-exported or type-only surfaces
217
217
 
218
218
  Local source modules: [src/commands/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/buddy/src/commands/index.ts).
219
219
 
220
- Evidence directory: [176 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/buddy/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
220
+ Evidence directory: [177 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/buddy/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
221
221
 
222
222
  ### @stacksjs/build
223
223
 
@@ -235,7 +235,7 @@ Read the entrypoint and package export map for re-exported or type-only surfaces
235
235
 
236
236
  Local source modules: [src/drivers/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/cache/src/drivers/index.ts), [src/key.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/cache/src/key.ts).
237
237
 
238
- Evidence directory: [18 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/cache/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
238
+ Evidence directory: [23 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/cache/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
239
239
 
240
240
  ### @stacksjs/calendar-api
241
241
 
@@ -363,7 +363,7 @@ Declared runtime exports: `DateTime`, `addCalendarMonths`, `addDays`, `dateForma
363
363
 
364
364
  Local source modules: [src/calendar.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/datetime/src/calendar.ts), [src/format.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/datetime/src/format.ts), [src/local.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/datetime/src/local.ts), [src/now.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/datetime/src/now.ts), [src/parse.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/datetime/src/parse.ts), [src/schedule.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/datetime/src/schedule.ts), [src/zone.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/datetime/src/zone.ts).
365
365
 
366
- Evidence directory: [13 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/datetime/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
366
+ Evidence directory: [14 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/datetime/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
367
367
 
368
368
  ### @stacksjs/defaults
369
369
 
@@ -385,7 +385,7 @@ Evidence directory: [1 retained tests](https://github.com/stacksjs/stacks/blob/m
385
385
 
386
386
  Guidance: [`stacks-desktop`](../stacks-desktop/SKILL.md). Source: [storage/framework/core/desktop/src/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/desktop/src/index.ts).
387
387
 
388
- Declared runtime exports: `BUN_EXECUTABLE_MARKER`, `RESERVED_PLIST_KEYS`, `USERLAND_LAUNCHER`, `bundleDirectoryFor`, `codesignArgs`, `craftDevCommand`, `createUpdateManifestUrl`, `describeRuntimeDuplication`, `desktopAppVersion`, `desktopLauncherCompileArgs`, `dmgVolumeName`, `hasUserlandDesktopLauncher`, `isMachO`, `looksLikeBunExecutable`, `notarytoolAuthArgs`, `openDevWindow`, `plistValue`, `renderInfoPlist`, `renderUserlandPlistEntries`, `resolveCraftBinary`, `resolveCraftExecutable`, `resolveDesktopLauncher`, `resolveDevWindowUrl`, `resolveDmgPackaging`, `xmlEscape`.
388
+ Declared runtime exports: `BUN_EXECUTABLE_MARKER`, `RESERVED_PLIST_KEYS`, `USERLAND_LAUNCHER`, `bundleDirectoryFor`, `codesignArgs`, `craftDevCommand`, `createUpdateManifestUrl`, `describeRuntimeDuplication`, `desktopAppVersion`, `desktopLauncherCompileArgs`, `developerIdProblem`, `dmgVolumeName`, `hasUserlandDesktopLauncher`, `isMachO`, `looksLikeBunExecutable`, `notarizationOutcome`, `notarytoolAuthArgs`, `openDevWindow`, `plistValue`, `renderInfoPlist`, `renderUserlandPlistEntries`, `resolveCraftBinary`, `resolveCraftExecutable`, `resolveDesktopLauncher`, `resolveDevWindowUrl`, `resolveDmgPackaging`, `xmlEscape`.
389
389
 
390
390
  Local source modules: [src/agent-launcher.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/desktop/src/agent-launcher.ts), [src/agent.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/desktop/src/agent.ts), [src/invites.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/desktop/src/invites.ts), [src/macos-app.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/desktop/src/macos-app.ts), [src/macos-bundle.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/desktop/src/macos-bundle.ts), [src/support.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/desktop/src/support.ts), [src/updater.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/desktop/src/updater.ts).
391
391
 
@@ -559,9 +559,9 @@ Guidance: [`stacks-image`](../stacks-image/SKILL.md). Source: [storage/framework
559
559
 
560
560
  Declared runtime exports: `ImageBuilder`, `image`, `imageResponseHeaders`, `negotiateImageVariant`, `resolveImageSource`, `signImageTransform`, `verifyImageTransform`.
561
561
 
562
- Local source modules: [src/app-icons.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/image/src/app-icons.ts), [src/app-store.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/image/src/app-store.ts), [src/fonts.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/image/src/fonts.ts), [src/generate.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/image/src/generate.ts), [src/social.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/image/src/social.ts), [src/theme.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/image/src/theme.ts).
562
+ Local source modules: [src/app-icons.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/image/src/app-icons.ts), [src/app-store.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/image/src/app-store.ts), [src/fonts.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/image/src/fonts.ts), [src/generate.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/image/src/generate.ts), [src/social.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/image/src/social.ts), [src/theme.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/image/src/theme.ts), [src/upload.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/image/src/upload.ts).
563
563
 
564
- Evidence directory: [2 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/image/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
564
+ Evidence directory: [3 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/image/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
565
565
 
566
566
  ### @stacksjs/lint
567
567
 
@@ -833,7 +833,7 @@ Declared runtime exports: `PathSanitizeError`, `Storage`, `StorageManager`, `Upl
833
833
 
834
834
  Local source modules: [src/adapters/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/adapters/index.ts), [src/bounded-text-file.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/bounded-text-file.ts), [src/completed-artifact-directory.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/completed-artifact-directory.ts), [src/copy.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/copy.ts), [src/delete.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/delete.ts), [src/drivers/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/drivers/index.ts), [src/facade.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/facade.ts), [src/file-info.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/file-info.ts), [src/files.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/files.ts), [src/folders.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/folders.ts), [src/fs.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/fs.ts), [src/glob.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/glob.ts), [src/hash.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/hash.ts), [src/helpers.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/helpers.ts), [src/mime-verify.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/mime-verify.ts), [src/path-sanitize.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/path-sanitize.ts), [src/provision.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/provision.ts), [src/s3-presigned-post.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/s3-presigned-post.ts), [src/signed-url.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/signed-url.ts), [src/static-serve.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/static-serve.ts), [src/storage.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/storage.ts), [src/temporary-workspaces.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/temporary-workspaces.ts), [src/types.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/types.ts), [src/types/filesystem.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/types/filesystem.ts), [src/uploaded-file.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/uploaded-file.ts), [src/zip.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/src/zip.ts).
835
835
 
836
- Evidence directory: [42 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
836
+ Evidence directory: [47 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/storage/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
837
837
 
838
838
  ### @stacksjs/strings
839
839
 
@@ -851,9 +851,9 @@ Guidance: [`stacks-testing`](../stacks-testing/SKILL.md). Source: [storage/frame
851
851
 
852
852
  Read the entrypoint and package export map for re-exported or type-only surfaces.
853
853
 
854
- Local source modules: [src/console.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/console.ts), [src/disposable-database.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/disposable-database.ts), [src/events.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/events.ts), [src/feature.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/feature.ts), [src/isolated.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/isolated.ts), [src/mail.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/mail.ts), [src/schema.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/schema.ts), [src/time.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/time.ts).
854
+ Local source modules: [src/console.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/console.ts), [src/disposable-database.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/disposable-database.ts), [src/events.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/events.ts), [src/feature.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/feature.ts), [src/isolated.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/isolated.ts), [src/mail.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/mail.ts), [src/schema.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/schema.ts), [src/service.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/service.ts), [src/time.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/src/time.ts).
855
855
 
856
- Evidence directory: [20 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
856
+ Evidence directory: [21 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/testing/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
857
857
 
858
858
  ### @stacksjs/tinker
859
859
 
@@ -154,6 +154,8 @@ The lightweight root also exports:
154
154
  the real mail singleton through the capture driver and restore automatically.
155
155
  - `freezeTime`, `travelTo`, `useRealTime`. Explicitly register
156
156
  `afterEach(useRealTime)`; frozen time is not restored implicitly.
157
+ Standalone Bun fixtures import these from `@stacksjs/testing/time` and
158
+ restore the clock in `finally`; this subpath imports no lifecycle hooks.
157
159
  - `command(args)` returns an awaitable child-process builder with `withInput`,
158
160
  `withEnv`, `withCwd` and `withTimeout`. Assert exitCode/output/timedOut. Run
159
161
  file-writing commands in a disposable fixture project using `withCwd`.
@@ -78,7 +78,7 @@ export interface CompleteRequestDeps {
78
78
  }
79
79
 
80
80
  export interface CompleteRequestResult {
81
- status: number
81
+ status: 200 | 401 | 422 | 502 | 503
82
82
  body: { completion: string } | { message: string }
83
83
  }
84
84
 
@@ -2,7 +2,7 @@
2
2
  "publisher": "Stacks",
3
3
  "name": "vscode-stacks",
4
4
  "displayName": "Stacks",
5
- "version": "0.75.409",
5
+ "version": "0.75.418",
6
6
  "description": "Stacks, built into VS Code: stx templates, pickier linting and formatting, encrypted env files, the dev server preview and every buddy command. No other extensions required.",
7
7
  "license": "MIT",
8
8
  "funding": "https://github.com/sponsors/chrisbbreuer",
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/defaults",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.75.409",
5
+ "version": "0.75.418",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/stacksjs/stacks.git",
@@ -45,7 +45,7 @@
45
45
  "dependencies": {
46
46
  "@iconify-json/f7": "^1.2.2",
47
47
  "@iconify-json/hugeicons": "^1.2.35",
48
- "@stacksjs/mobile": "0.75.409",
48
+ "@stacksjs/mobile": "0.75.418",
49
49
  "@stacksjs/sanitizer": "0.2.780",
50
50
  "@stacksjs/stx": "0.2.780",
51
51
  "@xterm/addon-fit": "^0.11.0",