@stacksjs/defaults 0.75.337 → 0.75.339

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.
@@ -11,8 +11,8 @@ Browser runtime bindings are documented separately in `stacks-auto-imports`.
11
11
  | Package | Task guidance | Source entry | Retained tests |
12
12
  |---|---|---|---|
13
13
  | `@stacksjs/action-runner` | [`stacks-actions`](../stacks-actions/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/action-runner/src/index.ts) | 1 |
14
- | `@stacksjs/actions` | [`stacks-actions`](../stacks-actions/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/index.ts) | 90 |
15
- | `@stacksjs/ai` | [`stacks-ai`](../stacks-ai/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/index.ts) | 17 |
14
+ | `@stacksjs/actions` | [`stacks-actions`](../stacks-actions/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/index.ts) | 91 |
15
+ | `@stacksjs/ai` | [`stacks-ai`](../stacks-ai/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/index.ts) | 18 |
16
16
  | `@stacksjs/alias` | [`stacks-alias`](../stacks-alias/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/alias/src/index.ts) | 1 |
17
17
  | `@stacksjs/analytics` | [`stacks-analytics`](../stacks-analytics/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/analytics/src/index.ts) | 6 |
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 |
@@ -21,7 +21,7 @@ Browser runtime bindings are documented separately in `stacks-auto-imports`.
21
21
  | `@stacksjs/auth` | [`stacks-auth`](../stacks-auth/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/index.ts) | 120 |
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
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) | 169 |
24
+ | `@stacksjs/buddy` | [`stacks-buddy`](../stacks-buddy/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/buddy/src/index.ts) | 170 |
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) | 4 |
26
26
  | `@stacksjs/cache` | [`stacks-cache`](../stacks-cache/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/cache/src/index.ts) | 14 |
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 |
@@ -68,14 +68,14 @@ Browser runtime bindings are documented separately in `stacks-auto-imports`.
68
68
  | `@stacksjs/orm` | [`stacks-orm`](../stacks-orm/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/index.ts) | 73 |
69
69
  | `@stacksjs/pagination` | [`stacks-pagination`](../stacks-pagination/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/pagination/src/index.ts) | 0 |
70
70
  | `@stacksjs/path` | [`stacks-path`](../stacks-path/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/path/src/index.ts) | 13 |
71
- | `@stacksjs/payments` | [`stacks-payments`](../stacks-payments/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/payments/src/index.ts) | 29 |
71
+ | `@stacksjs/payments` | [`stacks-payments`](../stacks-payments/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/payments/src/index.ts) | 30 |
72
72
  | `@stacksjs/push` | [`stacks-push`](../stacks-push/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/push/src/index.ts) | 6 |
73
73
  | `@stacksjs/query-builder` | [`stacks-query-builder`](../stacks-query-builder/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/query-builder/src/index.ts) | 6 |
74
74
  | `@stacksjs/queue` | [`stacks-queue`](../stacks-queue/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/queue/src/index.ts) | 49 |
75
75
  | `@stacksjs/realtime` | [`stacks-realtime`](../stacks-realtime/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/realtime/src/index.ts) | 12 |
76
76
  | `@stacksjs/registry` | [`stacks-registry`](../stacks-registry/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/registry/src/index.ts) | 1 |
77
77
  | `@stacksjs/repl` | [`stacks-repl`](../stacks-repl/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/repl/src/index.ts) | 2 |
78
- | `@stacksjs/router` | [`stacks-router`](../stacks-router/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/index.ts) | 96 |
78
+ | `@stacksjs/router` | [`stacks-router`](../stacks-router/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/index.ts) | 97 |
79
79
  | `@stacksjs/scheduler` | [`stacks-scheduler`](../stacks-scheduler/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/scheduler/src/index.ts) | 14 |
80
80
  | `@stacksjs/search-engine` | [`stacks-search-engine`](../stacks-search-engine/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/search-engine/src/index.ts) | 11 |
81
81
  | `@stacksjs/security` | [`stacks-security`](../stacks-security/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/security/src/index.ts) | 11 |
@@ -119,7 +119,7 @@ Declared runtime exports: `BlogAdminError`, `DEFAULT_IOS_DEPENDENCIES`, `DEFAULT
119
119
 
120
120
  Local source modules: [src/action.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/action.ts), [src/add.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/add.ts), [src/blog-admin.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/blog-admin.ts), [src/build/ios-toolchain.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/build/ios-toolchain.ts), [src/commit.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/commit.ts), [src/dev/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/dev/index.ts), [src/discover-packages.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/discover-packages.ts), [src/generate/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/generate/index.ts), [src/github-release.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/github-release.ts), [src/helpers/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/helpers/index.ts), [src/library/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/library/index.ts), [src/lint/lint.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/lint/lint.ts), [src/lint/stx-gate.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/lint/stx-gate.ts), [src/make-command.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/make-command.ts), [src/make-job.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/make-job.ts), [src/make-policy.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/make-policy.ts), [src/make-resource.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/make-resource.ts), [src/make.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/make.ts), [src/publication-preflight.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/publication-preflight.ts), [src/release-evidence.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/release-evidence.ts), [src/scaffold-crud.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/scaffold-crud.ts), [src/setup/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/setup/index.ts), [src/stacks.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/stacks.ts), [src/stx-source.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/stx-source.ts), [src/upgrade/package-project.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/upgrade/package-project.ts), [src/upgrade/route-actions.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/src/upgrade/route-actions.ts).
121
121
 
122
- Evidence directory: [90 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
122
+ Evidence directory: [91 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/actions/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
123
123
 
124
124
  ### @stacksjs/ai
125
125
 
@@ -127,9 +127,9 @@ Guidance: [`stacks-ai`](../stacks-ai/SKILL.md). Source: [storage/framework/core/
127
127
 
128
128
  Declared runtime exports: `assistantTurn`, `buildMessageWithImages`, `clearUsageReporters`, `estimateMessageTokens`, `estimateTokens`, `fetchWithRetry`, `listUsageReporters`, `normalizeMessagesForProvider`, `onUsage`, `recordUsage`, `sanitizePrompt`, `toolResultsTurn`.
129
129
 
130
- Local source modules: [src/agents/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/agents/index.ts), [src/buddy.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/buddy.ts), [src/client.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/client.ts), [src/context.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/context.ts), [src/drivers/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/drivers/index.ts), [src/image.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/image.ts), [src/mcp-server.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/mcp-server.ts), [src/mcp.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/mcp.ts), [src/models.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/models.ts), [src/personalization.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/personalization.ts), [src/search.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/search.ts), [src/speech.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/speech.ts), [src/text.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/text.ts), [src/types.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/types.ts), [src/utils/client-bedrock-runtime.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/utils/client-bedrock-runtime.ts), [src/utils/client-bedrock.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/utils/client-bedrock.ts), [src/utils/model-access.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/utils/model-access.ts), [src/utils/retry.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/utils/retry.ts), [src/utils/tokens.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/utils/tokens.ts), [src/utils/tools.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/utils/tools.ts), [src/utils/usage.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/utils/usage.ts), [src/utils/vision.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/utils/vision.ts).
130
+ Local source modules: [src/agents/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/agents/index.ts), [src/buddy.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/buddy.ts), [src/client.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/client.ts), [src/context.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/context.ts), [src/documents.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/documents.ts), [src/drivers/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/drivers/index.ts), [src/image.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/image.ts), [src/mcp-server.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/mcp-server.ts), [src/mcp.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/mcp.ts), [src/models.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/models.ts), [src/personalization.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/personalization.ts), [src/search.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/search.ts), [src/speech.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/speech.ts), [src/text.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/text.ts), [src/types.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/types.ts), [src/utils/client-bedrock-runtime.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/utils/client-bedrock-runtime.ts), [src/utils/client-bedrock.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/utils/client-bedrock.ts), [src/utils/model-access.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/utils/model-access.ts), [src/utils/retry.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/utils/retry.ts), [src/utils/tokens.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/utils/tokens.ts), [src/utils/tools.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/utils/tools.ts), [src/utils/usage.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/utils/usage.ts), [src/utils/vision.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/src/utils/vision.ts).
131
131
 
132
- Evidence directory: [17 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
132
+ Evidence directory: [18 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ai/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
133
133
 
134
134
  ### @stacksjs/alias
135
135
 
@@ -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: [169 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: [170 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
 
@@ -661,7 +661,7 @@ Declared runtime exports: `Payment`, `freshIdempotencyKey`, `stacksIdempotencyKe
661
661
 
662
662
  Local source modules: [src/billable/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/payments/src/billable/index.ts), [src/checkout-outcome.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/payments/src/checkout-outcome.ts), [src/connect/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/payments/src/connect/index.ts), [src/direct-debit.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/payments/src/direct-debit.ts), [src/driver/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/payments/src/driver/index.ts), [src/drivers/stripe.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/payments/src/drivers/stripe.ts), [src/idempotency.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/payments/src/idempotency.ts), [src/payment.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/payments/src/payment.ts), [src/subscription-state.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/payments/src/subscription-state.ts), [src/terminal.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/payments/src/terminal.ts).
663
663
 
664
- Evidence directory: [29 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/payments/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
664
+ Evidence directory: [30 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/payments/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
665
665
 
666
666
  ### @stacksjs/push
667
667
 
@@ -721,11 +721,11 @@ Evidence directory: [2 retained tests](https://github.com/stacksjs/stacks/blob/m
721
721
 
722
722
  Guidance: [`stacks-router`](../stacks-router/SKILL.md). Source: [storage/framework/core/router/src/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/index.ts).
723
723
 
724
- Declared runtime exports: `DASHBOARD_ROUTE_GROUPS`, `DEFAULT_ROUTE_BUNDLE_FEATURES`, `DEFAULT_ROUTE_REGISTRY`, `DatabaseSessionStore`, `EncryptedSessionStore`, `FileSessionStore`, `JSON_CONTENT_TYPE`, `MemorySessionStore`, `Middleware`, `PathParamError`, `RedisSessionStore`, `RequestBodyError`, `appRouteRegistry`, `assertRouteMiddlewareResolvable`, `bundleMounts`, `cacheRedisConnection`, `cacheRequestQuery`, `checkApplicationHealth`, `clearCsrfModuleCache`, `clearCurrentRequest`, `clearMiddlewareCache`, `clearRateLimit`, `clearRouteModelBindings`, `clearTrackedQueries`, `clientAddress`, `configureViewDirectories`, `createErrorResponse`, `createMiddlewareErrorResponse`, `createNotFoundResponse`, `createSessionStore`, `createStacksRouter`, `createStacksSessionStore`, `createTypedRouter`, `createValidationErrorResponse`, `dashboardGroupMiddleware`, `defineMiddleware`, `defineRouteModelBinding`, `describeUnknownDashboardGroups`, `disableViewRouting`, `enhanceRequest`, `fallbackStorage`, `findUnresolvableRouteMiddleware`, `getCurrentRequest`, `getQueryShapeCounts`, `getTraceId`, `installMiddlewareHotReload`, `isApiRequest`, `isRouterAction`, `listNamedRoutes`, `listRedirectRoutes`, `listRegisteredRoutes`, `listRootMountedAppRoutes`, `loadMiddlewareHandlers`, `loadRoutes`, `mountedDefaultRouteBundles`, `parseJsonText`, `rateLimit`, `rateLimitScale`, `rateLimitStatus`, `readJsonBody`, `readTextBody`, `request`, `resetBootHooks`, `resetRateLimiters`, `resetSharedRateLimitStorage`, `resolveDashboardAccess`, `resolveRouteModel`, `route`, `routeModelBindings`, `routeParams`, `runBootHooks`, `runHealthProbes`, `runWithRequest`, `safePathParam`, `sanitizePathParam`, `scaledLimit`, `serve`, `serverResponse`, `setCurrentRequest`, `setRouteModelFallback`, `sharedRateLimitStorage`, `signUrl`, `signedUrl`, `stream`, `trackQuery`, `trustedProxies`, `url`, `useRateLimitStorage`, `verifySignedUrl`, `verifySignedUrlMiddleware`, `warnOnMultipleRouterInstances`, `withRouteAdmission`, `withTraceId`, `wrapAction`.
724
+ Declared runtime exports: `DASHBOARD_ROUTE_GROUPS`, `DEFAULT_ROUTE_BUNDLE_FEATURES`, `DEFAULT_ROUTE_REGISTRY`, `DatabaseSessionStore`, `EncryptedSessionStore`, `FileSessionStore`, `JSON_CONTENT_TYPE`, `MemorySessionStore`, `Middleware`, `PathParamError`, `RedisSessionStore`, `RequestBodyError`, `appRouteRegistry`, `assertRouteMiddlewareResolvable`, `bundleMounts`, `cacheRedisConnection`, `cacheRequestQuery`, `checkApplicationHealth`, `clearCsrfModuleCache`, `clearCurrentRequest`, `clearMiddlewareCache`, `clearRateLimit`, `clearRouteModelBindings`, `clearTrackedQueries`, `clientAddress`, `configureViewDirectories`, `createErrorResponse`, `createMiddlewareErrorResponse`, `createNotFoundResponse`, `createSessionStore`, `createStacksRouter`, `createStacksSessionStore`, `createTypedRouter`, `createValidationErrorResponse`, `dashboardGroupMiddleware`, `defineMiddleware`, `defineRouteModelBinding`, `describeUnknownDashboardGroups`, `disableViewRouting`, `enhanceRequest`, `fallbackStorage`, `findUnresolvableRouteMiddleware`, `getCurrentRequest`, `getQueryShapeCounts`, `getTraceId`, `installMiddlewareHotReload`, `isApiRequest`, `isRouterAction`, `listNamedRoutes`, `listRedirectRoutes`, `listRegisteredRoutes`, `listRootMountedAppRoutes`, `loadMiddlewareHandlers`, `loadRoutes`, `mountedDefaultRouteBundles`, `parseJsonText`, `rateLimit`, `rateLimitScale`, `rateLimitStatus`, `readJsonBody`, `readTextBody`, `request`, `resetBootHooks`, `resetRateLimiters`, `resetSharedRateLimitStorage`, `resetShutdownHooks`, `resolveDashboardAccess`, `resolveRouteModel`, `route`, `routeModelBindings`, `routeParams`, `runBootHooks`, `runHealthProbes`, `runShutdownHooks`, `runWithRequest`, `safePathParam`, `sanitizePathParam`, `scaledLimit`, `serve`, `serverResponse`, `setCurrentRequest`, `setRouteModelFallback`, `sharedRateLimitStorage`, `signUrl`, `signedUrl`, `stream`, `trackQuery`, `trustedProxies`, `url`, `useRateLimitStorage`, `verifySignedUrl`, `verifySignedUrlMiddleware`, `warnOnMultipleRouterInstances`, `withRouteAdmission`, `withTraceId`, `wrapAction`.
725
725
 
726
726
  Local source modules: [src/api-shape.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/api-shape.ts), [src/body.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/body.ts), [src/dashboard-access.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/dashboard-access.ts), [src/encrypted-session-store.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/encrypted-session-store.ts), [src/error-handler.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/error-handler.ts), [src/health.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/health.ts), [src/json.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/json.ts), [src/middleware.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/middleware.ts), [src/path-sanitize.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/path-sanitize.ts), [src/rate-limit.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/rate-limit.ts), [src/request-augmentation.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/request-augmentation.ts), [src/request-context.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/request-context.ts), [src/route-loader.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/route-loader.ts), [src/route-model-binding.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/route-model-binding.ts), [src/security-settings.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/security-settings.ts), [src/session-factory.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/session-factory.ts), [src/signed-url.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/signed-url.ts), [src/stacks-router.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/stacks-router.ts), [src/typed-router.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/src/typed-router.ts).
727
727
 
728
- Evidence directory: [96 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
728
+ Evidence directory: [97 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/router/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
729
729
 
730
730
  ### @stacksjs/scheduler
731
731
 
@@ -417,6 +417,31 @@ await serve({ port: 3000 })
417
417
  const response = await serverResponse(request)
418
418
  ```
419
419
 
420
+ ### Boot and shutdown hooks
421
+
422
+ ```typescript
423
+ import { route } from '@stacksjs/router'
424
+
425
+ // Once, after the routes load and before the first request. Optional
426
+ // preparation only: a hook that throws is logged and the boot continues.
427
+ route.booting('warm grammars', () => highlighter.load())
428
+
429
+ // When the server is told to stop. For whatever would otherwise outlive the
430
+ // process or end unrecorded: open sessions, child processes, a buffer to flush.
431
+ route.stopping('terminal sessions', () => terminalSessions.closeAll())
432
+ ```
433
+
434
+ - Boot hooks run in order, once per process, from `serve()`.
435
+ - Shutdown hooks run concurrently, once per process (a second signal waits on
436
+ the same run). One that throws is logged and the rest still run.
437
+ - The production API server (`core/actions/src/serve/api.ts`) runs them on
438
+ SIGTERM alongside draining in-flight requests. `SHUTDOWN_GRACE_MS` (default
439
+ fifteen seconds) caps both, so a hook that hangs cannot hold the process.
440
+ - The list lives on `globalThis`, so a module registering through a second copy
441
+ of `@stacksjs/router` still reaches the one the server runs.
442
+ - `buddy dev:api` has no shutdown handler: Ctrl-C ends the process group, and
443
+ shutdown hooks do not run there.
444
+
420
445
  ## URL Generation
421
446
 
422
447
  ```typescript
@@ -1,13 +1,14 @@
1
1
  import type { UserModel } from '@stacksjs/orm'
2
2
  import type { RemoteHost } from './remote-commands'
3
3
  import type { TerminalAuditSink, TerminalEvent, TerminalProcess, TerminalSessionOptions } from './remote-terminal'
4
- import { describe, expect, it } from 'bun:test'
5
- import { existsSync, readdirSync } from 'node:fs'
4
+ import { describe, expect, it, jest } from 'bun:test'
5
+ import { existsSync } from 'node:fs'
6
6
  import { tmpdir } from 'node:os'
7
+ import { dirname } from 'node:path'
7
8
  import { sshTerminalArgv } from './remote-commands'
8
9
  import { TerminalSessions } from './remote-terminal'
9
10
  import { createPtySpawner } from './ssh-runner'
10
- import { encodeTerminalEvent, terminalEventStream } from './terminal-sessions'
11
+ import { encodeTerminalEvent, terminalEventStream, terminalSessions } from './terminal-sessions'
11
12
 
12
13
  /**
13
14
  * Interactive terminal sessions (stacksjs/stacks#960). Every rule is asserted
@@ -236,16 +237,28 @@ describe('a session does not outlive its purpose', () => {
236
237
  })
237
238
 
238
239
  it('input keeps it alive; the max duration ends it regardless', async () => {
239
- const { manager, fakes, audit } = sessions({ idleTimeoutMs: 40, maxDurationMs: 120, detachGraceMs: 10_000 })
240
- const { id } = await manager.open({ user: alice, hosts, hostKey: 'app', authorizer: allowAll, cols: 80, rows: 24 })
241
- for (let i = 0; i < 4; i++) {
242
- await Bun.sleep(25)
243
- await manager.input(id, alice, 'x')
240
+ // The clock is driven, not slept on: the deadlines under test run on the
241
+ // same clock a sleep waits on, so under load a sleep overshot them (#2978).
242
+ jest.useFakeTimers()
243
+ try {
244
+ const { manager, fakes, audit } = sessions({ idleTimeoutMs: 40, maxDurationMs: 120, detachGraceMs: 10_000 })
245
+ const { id } = await manager.open({ user: alice, hosts, hostKey: 'app', authorizer: allowAll, cols: 80, rows: 24 })
246
+ for (let i = 0; i < 4; i++) {
247
+ jest.advanceTimersByTime(25)
248
+ await manager.input(id, alice, 'x')
249
+ }
250
+ const ending = take(manager.watch(id, alice), 1)
251
+ // 119ms in: more than twice the idle timeout, kept open by the input.
252
+ jest.advanceTimersByTime(19)
253
+ expect(fakes[0]!.killed).toBe(false)
254
+ jest.advanceTimersByTime(1)
255
+ expect(fakes[0]!.killed).toBe(true)
256
+ expect((await ending).map(text)).toEqual(['<max-duration>'])
257
+ expect(audit.log.at(-1)).toStartWith('closed max-duration')
258
+ }
259
+ finally {
260
+ jest.useRealTimers()
244
261
  }
245
- expect(fakes[0]!.killed).toBe(false)
246
- await Bun.sleep(60)
247
- expect(fakes[0]!.killed).toBe(true)
248
- expect(audit.log.at(-1)).toStartWith('closed max-duration')
249
262
  })
250
263
 
251
264
  it('ends when nobody attaches, and a grace period after the last viewer leaves', async () => {
@@ -272,6 +285,40 @@ describe('a session does not outlive its purpose', () => {
272
285
  await expect(manager.close(id, alice)).rejects.toThrow('No such terminal session')
273
286
  expect(audit.log.slice(1)).toEqual(['input rm -rf /tmp/build', 'closed closed in=17 out=0'])
274
287
  })
288
+
289
+ it('shuts down only once every process has exited, so nothing it made outlives it', async () => {
290
+ // The real spawner removes its temp directory when the process exits; a
291
+ // shutdown that returned on the kill raced the process exiting (#2978).
292
+ let exit!: (code: number) => void
293
+ const { manager } = sessions({
294
+ spawn: () => ({ write: () => {}, resize: () => {}, kill: () => {}, exited: new Promise<number>((resolve) => { exit = resolve }) }),
295
+ })
296
+ await manager.open({ user: alice, hosts, hostKey: 'app', authorizer: allowAll, cols: 80, rows: 24 })
297
+
298
+ const closing = manager.closeAll().then(() => 'closed')
299
+ expect(await Promise.race([closing, Bun.sleep(20).then(() => 'waiting')])).toBe('waiting')
300
+ exit(-1)
301
+ expect(await closing).toBe('closed')
302
+ })
303
+
304
+ it('is closed by the server stopping, through the router\'s shutdown hooks (#3034)', async () => {
305
+ const registered = (globalThis as Record<symbol, { hooks: Array<{ name: string, run: () => unknown }> }>)[Symbol.for('@stacksjs/router:shutdown-hooks')]
306
+ const hook = registered?.hooks.find(entry => entry.name === 'terminal sessions')
307
+ expect(hook).toBeDefined()
308
+
309
+ // The app's own sessions, not a copy: the hook has to reach the manager
310
+ // the terminal actions open sessions on.
311
+ const closeAll = terminalSessions.closeAll
312
+ let closed = 0
313
+ terminalSessions.closeAll = async () => { closed += 1 }
314
+ try {
315
+ await hook!.run()
316
+ }
317
+ finally {
318
+ terminalSessions.closeAll = closeAll
319
+ }
320
+ expect(closed).toBe(1)
321
+ })
275
322
  })
276
323
 
277
324
  describe('the event stream', () => {
@@ -304,7 +351,6 @@ describe('the PTY spawner', () => {
304
351
  })
305
352
 
306
353
  it('carries output, input and a window resize through a real PTY, and cleans up', async () => {
307
- const before = readdirSync(tmpdir()).filter(name => name.startsWith('stacks-terminal-')).length
308
354
  let knownHosts = ''
309
355
  const spawn = createPtySpawner((_host, path) => {
310
356
  knownHosts = path
@@ -315,7 +361,10 @@ describe('the PTY spawner', () => {
315
361
  const process = await spawn(shellHost, { cols: 100, rows: 30 }, (bytes) => { output += new TextDecoder().decode(bytes) })
316
362
  expect(existsSync(knownHosts)).toBe(true)
317
363
 
318
- await Bun.sleep(150)
364
+ // Resize once the shell has reported the size it started at, not after a
365
+ // guess at how long that takes.
366
+ for (let i = 0; i < 200 && !output.includes('30 100'); i++)
367
+ await Bun.sleep(10)
319
368
  process.resize(132, 40)
320
369
  process.write('hello\r')
321
370
  expect(await process.exited).toBe(0)
@@ -324,8 +373,9 @@ describe('the PTY spawner', () => {
324
373
  expect(output).toContain('30 100')
325
374
  expect(output).toContain('40 132')
326
375
  expect(output).toContain('got:hello')
327
- expect(existsSync(knownHosts)).toBe(false)
328
- expect(readdirSync(tmpdir()).filter(name => name.startsWith('stacks-terminal-')).length).toBe(before)
376
+ // The directory this spawn created, not a count of the shared temp
377
+ // directory, which other processes change underneath the test (#2978).
378
+ expect(existsSync(dirname(knownHosts))).toBe(false)
329
379
  })
330
380
  })
331
381
 
@@ -261,9 +261,15 @@ export class TerminalSessions {
261
261
  await this.end(this.find(id, user), 'closed')
262
262
  }
263
263
 
264
- /** End every session, for a server shutting down. */
264
+ /**
265
+ * End every session, for a server shutting down, and wait for each process
266
+ * to exit: the spawner cleans up after the process, and a server that exits
267
+ * first leaves that behind.
268
+ */
265
269
  async closeAll(): Promise<void> {
266
- await Promise.all([...this.sessions.values()].map(session => this.end(session, 'shutdown')))
270
+ const open = [...this.sessions.values()]
271
+ await Promise.all(open.map(session => this.end(session, 'shutdown')))
272
+ await Promise.all(open.map(session => session.process.exited))
267
273
  }
268
274
 
269
275
  /**
@@ -1,5 +1,6 @@
1
1
  import type { TerminalAuthorizer, TerminalEvent } from './remote-terminal'
2
2
  import { Gate } from '@stacksjs/auth'
3
+ import { route } from '@stacksjs/router'
3
4
  import { TerminalSessions } from './remote-terminal'
4
5
  import { createPtySpawner, loggingTerminalAuditSink } from './ssh-runner'
5
6
 
@@ -18,6 +19,10 @@ export const terminalSessions: TerminalSessions = new TerminalSessions({
18
19
  audit: loggingTerminalAuditSink,
19
20
  })
20
21
 
22
+ // A server that stops closes its sessions first, so each one records why it
23
+ // ended and its temp directory goes with its process (stacksjs/stacks#3034).
24
+ route.stopping('terminal sessions', () => terminalSessions.closeAll())
25
+
21
26
  /**
22
27
  * The `open-remote-terminal` gate, or undefined when the app has not defined
23
28
  * it - and `TerminalSessions.open` refuses in that case rather than proceeding.
@@ -2,7 +2,7 @@
2
2
  "publisher": "Stacks",
3
3
  "name": "vscode-stacks",
4
4
  "displayName": "Stacks",
5
- "version": "0.75.337",
5
+ "version": "0.75.339",
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.337",
5
+ "version": "0.75.339",
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.337",
48
+ "@stacksjs/mobile": "0.75.339",
49
49
  "@stacksjs/sanitizer": "0.2.736",
50
50
  "@stacksjs/stx": "0.2.736",
51
51
  "@xterm/addon-fit": "^0.11.0",
@@ -221,7 +221,7 @@ onMount(() => {
221
221
  <span class="h-4 w-4 i-hugeicons-key-02"></span>
222
222
  Create Token
223
223
  </Button>
224
- <Button :if="!loading() && authenticationRequired()" tag="a" href="/login">
224
+ <Button :if="!loading() && authenticationRequired()" tag="a" href="/login?redirect=/access-tokens">
225
225
  <span class="h-4 w-4 i-hugeicons-login-03"></span>
226
226
  Sign in
227
227
  </Button>
@@ -271,7 +271,7 @@ onMount(() => {
271
271
  description="Personal access tokens belong to an authenticated account. Sign in to create, inspect, or revoke them."
272
272
  >
273
273
  <template #action>
274
- <Button tag="a" href="/login">
274
+ <Button tag="a" href="/login?redirect=/access-tokens">
275
275
  <span class="h-4 w-4 i-hugeicons-login-03"></span>
276
276
  Sign in
277
277
  </Button>
@@ -1,5 +1,6 @@
1
1
  <script client>
2
2
  import type { RemoteCommandResult, RemoteRegistry } from '../../../../functions/remote'
3
+ import { DashboardApiError } from '../../../../functions/dashboard-api'
3
4
  import { fetchRemoteRegistry, requestRemoteCommand } from '../../../../functions/remote'
4
5
  import { registerRemoteTerminal } from '../../../../functions/remote-terminal-element'
5
6
  import { pushToast } from '../../../../functions/toasts'
@@ -9,6 +10,9 @@ void registerRemoteTerminal()
9
10
  const registry = state<RemoteRegistry | null>(null)
10
11
  const isLoading = state(true)
11
12
  const loadError = state('')
13
+ // Remote access needs a signed-in account even where the rest of the dev
14
+ // dashboard does not, so a 401 here asks for a sign-in rather than failing.
15
+ const authenticationRequired = state(false)
12
16
  const selectedHost = state('')
13
17
  const selectedCommand = state('')
14
18
  const isRunning = state(false)
@@ -27,6 +31,7 @@ const commandsForHost = derived(() => {
27
31
  async function load(): Promise<void> {
28
32
  isLoading.set(true)
29
33
  loadError.set('')
34
+ authenticationRequired.set(false)
30
35
  try {
31
36
  const data = await fetchRemoteRegistry()
32
37
  registry.set(data)
@@ -34,7 +39,10 @@ async function load(): Promise<void> {
34
39
  selectedHost.set(data.hosts[0].key)
35
40
  }
36
41
  catch (error) {
37
- loadError.set(error instanceof Error ? error.message : 'The remote hosts could not be loaded.')
42
+ if (error instanceof DashboardApiError && error.status === 401)
43
+ authenticationRequired.set(true)
44
+ else
45
+ loadError.set(error instanceof Error ? error.message : 'The remote hosts could not be loaded.')
38
46
  }
39
47
  finally {
40
48
  isLoading.set(false)
@@ -87,6 +95,20 @@ onMount(() => {
87
95
 
88
96
  <div :if="isLoading()" class="text-gray-500 text-sm dark:text-neutral-400">Loading hosts</div>
89
97
 
98
+ <EmptyState
99
+ :if="!isLoading() && authenticationRequired()"
100
+ icon="i-hugeicons-user-lock-01"
101
+ title="Sign in to use remote access"
102
+ description="Running commands and opening terminals on your servers needs a signed-in account, in every environment. Each run and session is recorded under it."
103
+ >
104
+ <template #action>
105
+ <Button tag="a" href="/login?redirect=/remote">
106
+ <span class="h-4 w-4 i-hugeicons-login-03"></span>
107
+ Sign in
108
+ </Button>
109
+ </template>
110
+ </EmptyState>
111
+
90
112
  <section :if="!isLoading() && registry() && hosts().length === 0" class="p-6 bg-white dark:bg-neutral-800 border border-gray-200 rounded-lg dark:border-neutral-700">
91
113
  <h2 class="font-semibold text-gray-900 dark:text-white">No hosts are configured</h2>
92
114
  <p class="mt-1 max-w-2xl text-gray-500 text-sm dark:text-neutral-400">