@warlock.js/core 5.27.0 → 5.29.0

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.
Files changed (127) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/esm/cli/commands/openapi-generator.action.mjs +1 -1
  3. package/esm/cli/commands/openapi-generator.action.mjs.map +1 -1
  4. package/esm/cli/commands/postman-generator.action.mjs +47 -0
  5. package/esm/cli/commands/postman-generator.action.mjs.map +1 -0
  6. package/esm/cli/commands/postman-generator.command.mjs +43 -0
  7. package/esm/cli/commands/postman-generator.command.mjs.map +1 -0
  8. package/esm/cli/framework-cli-commands.mjs +2 -0
  9. package/esm/cli/framework-cli-commands.mjs.map +1 -1
  10. package/esm/container/development-app-modules.d.mts +31 -0
  11. package/esm/container/development-app-modules.d.mts.map +1 -0
  12. package/esm/container/index.d.mts +2 -0
  13. package/esm/container/index.d.mts.map +1 -1
  14. package/esm/container/index.mjs.map +1 -1
  15. package/esm/dev-server/app-module-registry.mjs +52 -0
  16. package/esm/dev-server/app-module-registry.mjs.map +1 -0
  17. package/esm/dev-server/files-orchestrator.mjs +13 -2
  18. package/esm/dev-server/files-orchestrator.mjs.map +1 -1
  19. package/esm/http/middleware/inject-request-context.d.mts.map +1 -1
  20. package/esm/http/middleware/inject-request-context.mjs +29 -3
  21. package/esm/http/middleware/inject-request-context.mjs.map +1 -1
  22. package/esm/http/request.d.mts +2 -2
  23. package/esm/http/request.d.mts.map +1 -1
  24. package/esm/index.d.mts +7 -2
  25. package/esm/index.mjs +5 -2
  26. package/esm/localization/parse-locale-dictionary.d.mts +6 -1
  27. package/esm/localization/parse-locale-dictionary.d.mts.map +1 -1
  28. package/esm/localization/parse-locale-dictionary.mjs +5 -1
  29. package/esm/localization/parse-locale-dictionary.mjs.map +1 -1
  30. package/esm/openapi/development-openapi-provider.d.mts +12 -1
  31. package/esm/openapi/development-openapi-provider.d.mts.map +1 -1
  32. package/esm/openapi/development-openapi-provider.mjs +15 -1
  33. package/esm/openapi/development-openapi-provider.mjs.map +1 -1
  34. package/esm/openapi/index.d.mts +5 -2
  35. package/esm/openapi/index.mjs +3 -1
  36. package/esm/openapi/postman/build-request-body.mjs +86 -0
  37. package/esm/openapi/postman/build-request-body.mjs.map +1 -0
  38. package/esm/openapi/postman/build-request-url.mjs +85 -0
  39. package/esm/openapi/postman/build-request-url.mjs.map +1 -0
  40. package/esm/openapi/postman/build-saved-responses.mjs +60 -0
  41. package/esm/openapi/postman/build-saved-responses.mjs.map +1 -0
  42. package/esm/openapi/postman/example-from-schema.d.mts +17 -0
  43. package/esm/openapi/postman/example-from-schema.d.mts.map +1 -0
  44. package/esm/openapi/postman/example-from-schema.mjs +92 -0
  45. package/esm/openapi/postman/example-from-schema.mjs.map +1 -0
  46. package/esm/openapi/postman/http-status-text.mjs +31 -0
  47. package/esm/openapi/postman/http-status-text.mjs.map +1 -0
  48. package/esm/openapi/postman/index.d.mts +3 -0
  49. package/esm/openapi/postman/openapi-to-postman-collection.d.mts +22 -0
  50. package/esm/openapi/postman/openapi-to-postman-collection.d.mts.map +1 -0
  51. package/esm/openapi/postman/openapi-to-postman-collection.mjs +109 -0
  52. package/esm/openapi/postman/openapi-to-postman-collection.mjs.map +1 -0
  53. package/esm/openapi/postman/postman-types.d.mts +119 -0
  54. package/esm/openapi/postman/postman-types.d.mts.map +1 -0
  55. package/esm/openapi/postman/resolve-operation-auth.mjs +51 -0
  56. package/esm/openapi/postman/resolve-operation-auth.mjs.map +1 -0
  57. package/esm/openapi/postman/schema-refs.d.mts +7 -0
  58. package/esm/openapi/postman/schema-refs.d.mts.map +1 -0
  59. package/esm/openapi/postman/schema-refs.mjs +41 -0
  60. package/esm/openapi/postman/schema-refs.mjs.map +1 -0
  61. package/esm/openapi/postman/uuid-v5.mjs +29 -0
  62. package/esm/openapi/postman/uuid-v5.mjs.map +1 -0
  63. package/esm/openapi/response-schemas.mjs +4 -1
  64. package/esm/openapi/response-schemas.mjs.map +1 -1
  65. package/esm/openapi/schema-registry.mjs +6 -0
  66. package/esm/openapi/schema-registry.mjs.map +1 -1
  67. package/esm/resource/index.d.mts +1 -0
  68. package/esm/resource/index.mjs +1 -0
  69. package/esm/resource/nullable-resource.d.mts +44 -0
  70. package/esm/resource/nullable-resource.d.mts.map +1 -0
  71. package/esm/resource/nullable-resource.mjs +38 -0
  72. package/esm/resource/nullable-resource.mjs.map +1 -0
  73. package/esm/resource/resource.d.mts.map +1 -1
  74. package/esm/resource/resource.mjs +24 -7
  75. package/esm/resource/resource.mjs.map +1 -1
  76. package/esm/resource/types.d.mts +10 -5
  77. package/esm/resource/types.d.mts.map +1 -1
  78. package/esm/restful/restful.d.mts +5 -5
  79. package/esm/restful/restful.d.mts.map +1 -1
  80. package/esm/router/response-schema-types.mjs +2 -0
  81. package/esm/router/response-schema-types.mjs.map +1 -1
  82. package/llms-full.txt +269 -241
  83. package/llms.txt +42 -42
  84. package/package.json +12 -12
  85. package/skills/README.md +39 -39
  86. package/skills/add-connector/SKILL.md +4 -4
  87. package/skills/benchmark-code/SKILL.md +3 -3
  88. package/skills/build-restful/SKILL.md +5 -5
  89. package/skills/build-url/SKILL.md +7 -7
  90. package/skills/configure-app/SKILL.md +7 -7
  91. package/skills/create-controller/SKILL.md +8 -8
  92. package/skills/create-module/SKILL.md +9 -9
  93. package/skills/define-resource/SKILL.md +4 -4
  94. package/skills/encrypt-data/SKILL.md +7 -7
  95. package/skills/generate-openapi/SKILL.md +33 -5
  96. package/skills/hash-password/SKILL.md +8 -8
  97. package/skills/health-checks/SKILL.md +6 -6
  98. package/skills/lower-stage3-decorators/SKILL.md +4 -4
  99. package/skills/process-image/SKILL.md +5 -5
  100. package/skills/register-route/SKILL.md +6 -6
  101. package/skills/request-memo/SKILL.md +4 -4
  102. package/skills/request-tracing/SKILL.md +6 -6
  103. package/skills/resolve-path/SKILL.md +6 -6
  104. package/skills/retry-operation/SKILL.md +4 -4
  105. package/skills/run-app/SKILL.md +11 -11
  106. package/skills/send-mail/SKILL.md +3 -3
  107. package/skills/send-response/SKILL.md +6 -6
  108. package/skills/store-file/SKILL.md +4 -4
  109. package/skills/test-http/SKILL.md +5 -5
  110. package/skills/test-service/SKILL.md +5 -5
  111. package/skills/update-packages/SKILL.md +6 -6
  112. package/skills/upload-file/SKILL.md +7 -7
  113. package/skills/use-app-context/SKILL.md +7 -7
  114. package/skills/use-localization/SKILL.md +6 -6
  115. package/skills/use-middleware/SKILL.md +6 -6
  116. package/skills/use-model-transformers/SKILL.md +6 -6
  117. package/skills/use-repository/SKILL.md +7 -7
  118. package/skills/use-request-locals/SKILL.md +4 -4
  119. package/skills/validate-input/SKILL.md +7 -7
  120. package/skills/warlock-conventions/SKILL.md +6 -6
  121. package/skills/warlock-doctor/SKILL.md +5 -5
  122. package/skills/warlock-routes/SKILL.md +6 -6
  123. package/skills/wire-socket/SKILL.md +4 -4
  124. package/skills/write-cli-command/SKILL.md +6 -6
  125. package/skills/write-middleware/SKILL.md +8 -8
  126. package/skills/write-seeder/SKILL.md +5 -5
  127. package/skills/write-use-case/SKILL.md +3 -3
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: send-mail
3
- description: 'Send transactional email — `Mail` fluent builder, `sendMail()` direct call, React Email components. Test mode auto-captures into an in-memory mailbox; dev mode logs. Triggers: `Mail.to`, `sendMail`, `setMailMode`, `mailEvents`, `assertMailSent`, `getTestMailbox`, `wasMailSentTo`, `closeAllMailers`; "send a transactional email", "build a React Email template", "configure SMTP or SES", "assert an email was sent in tests"; typical import `import { Mail, sendMail } from "@warlock.js/core"`. Skip: per-config wiring — `@warlock.js/core/configure-app/SKILL.md`; layered service patterns — `@warlock.js/core/warlock-conventions/SKILL.md`; competing libs `nodemailer` direct, `@sendgrid/mail`, `resend`, `mailgun.js`.'
3
+ description: 'Send transactional email — `Mail` fluent builder, `sendMail()` direct call, React Email components. Test mode auto-captures into an in-memory mailbox; dev mode logs. Triggers: `Mail.to`, `sendMail`, `setMailMode`, `mailEvents`, `assertMailSent`, `getTestMailbox`, `wasMailSentTo`, `closeAllMailers`; "send a transactional email", "build a React Email template", "configure SMTP or SES", "assert an email was sent in tests"; typical import `import { Mail, sendMail } from "@warlock.js/core"`. Skip: per-config wiring — the `configure-app` topic; layered service patterns — the `warlock-conventions` topic; competing libs `nodemailer` direct, `@sendgrid/mail`, `resend`, `mailgun.js`.'
4
4
  ---
5
5
 
6
6
  # Warlock — send a mail
@@ -398,5 +398,5 @@ await Mail.to(user.email)
398
398
 
399
399
  ## See also
400
400
 
401
- - [`configure-app/SKILL.md`](../configure-app/SKILL.md) — `src/config/mail.ts` shape and `env()` patterns.
402
- - [`warlock-conventions/SKILL.md`](../warlock-conventions/SKILL.md) — where mail-sending services live.
401
+ - The `configure-app` topic — `src/config/mail.ts` shape and `env()` patterns.
402
+ - The `warlock-conventions` topic — where mail-sending services live.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: send-response
3
- description: 'Send HTTP responses via @warlock.js/core''s Response helpers — success/error variants, status helpers, redirects, files, streams, and SSE. Picking the right helper carries the HTTP semantic without manual status codes. Triggers: `response.success`, `response.successCreate`, `response.notFound`, `response.forbidden`, `response.badRequest`, `response.sendFile`, `response.stream`, `response.sse`, `response.replay`, `ResourceNotFoundError`, `ForbiddenError`, `request.cookie`, `request.hasCookie`, `CookieJarUnavailableError`; "return a 201 from a controller", "send a file", "stream Server-Sent Events", "throw HTTP-shaped errors from services"; typical import `import type { RequestHandler, Response } from "@warlock.js/core"`. Skip: controller shape — `@warlock.js/core/create-controller/SKILL.md`; route registration — `@warlock.js/core/register-route/SKILL.md`; competing patterns: hand-rolled status codes via `reply.code(404).send(...)`, raw Fastify reply.'
3
+ description: 'Send HTTP responses via @warlock.js/core''s Response helpers — success/error variants, status helpers, redirects, files, streams, and SSE. Picking the right helper carries the HTTP semantic without manual status codes. Triggers: `response.success`, `response.successCreate`, `response.notFound`, `response.forbidden`, `response.badRequest`, `response.sendFile`, `response.stream`, `response.sse`, `response.replay`, `ResourceNotFoundError`, `ForbiddenError`, `request.cookie`, `request.hasCookie`, `CookieJarUnavailableError`; "return a 201 from a controller", "send a file", "stream Server-Sent Events", "throw HTTP-shaped errors from services"; typical import `import type { RequestHandler, Response } from "@warlock.js/core"`. Skip: controller shape — the `create-controller` topic; route registration — the `register-route` topic; competing patterns: hand-rolled status codes via `reply.code(404).send(...)`, raw Fastify reply.'
4
4
  ---
5
5
 
6
6
  # Warlock — send a response
@@ -145,7 +145,7 @@ export const getProductController: RequestHandler = async ({ request, response }
145
145
  };
146
146
  ```
147
147
 
148
- See [`create-controller`](../create-controller/SKILL.md) for the "throw from service, return from controller" pattern.
148
+ See the `create-controller` topic for the "throw from service, return from controller" pattern.
149
149
 
150
150
  ## Server-Sent Events
151
151
 
@@ -225,7 +225,7 @@ These mutate the response in place; chain or call before the final `return respo
225
225
  ### `Content-Security-Policy` (5.12.0)
226
226
 
227
227
  Opt in via `http.csp.enabled` in `src/config/http.ts` (see
228
- [`configure-app/SKILL.md`](../configure-app/SKILL.md) for the full shape).
228
+ the `configure-app` topic for the full shape).
229
229
  When enabled, every response through the shared request funnel
230
230
  (`http/middleware/inject-request-context.ts`, the same seam that stamps
231
231
  `X-Request-Id`) gets a `Content-Security-Policy` header — `-Report-Only`
@@ -305,6 +305,6 @@ return response.header("X-Cache", "HIT").replay({
305
305
 
306
306
  ## See also
307
307
 
308
- - [`create-controller/SKILL.md`](../create-controller/SKILL.md) — what calls `response.<helper>()` from.
309
- - [`register-route/SKILL.md`](../register-route/SKILL.md) — wiring the controller to a URL.
310
- - [`warlock-conventions/SKILL.md`](../warlock-conventions/SKILL.md) — when to use HTTP error helpers vs `throw`.
308
+ - The `create-controller` topic — what calls `response.<helper>()` from.
309
+ - The `register-route` topic — wiring the controller to a URL.
310
+ - The `warlock-conventions` topic — when to use HTTP error helpers vs `throw`.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: store-file
3
- description: 'Read/write/delete files via the `storage` singleton — disks, drivers (local/S3/R2/DO Spaces), `storage.use(name)`, `StorageFile` handles, presigned URLs. Triggers: `storage.put`, `storage.get`, `storage.use`, `StorageFile`, `storageConfigurations`, `getPresignedUrl`, `getPresignedUploadUrl`; "save an uploaded file", "switch between local and S3", "generate a presigned URL", "read file metadata"; typical import `import { storage } from "@warlock.js/core"`. Skip: multipart parsing + image chain — `@warlock.js/core/upload-file/SKILL.md`; image transforms — `@warlock.js/core/process-image/SKILL.md`; storage config shape — `@warlock.js/core/configure-app/SKILL.md`; competing libs `@aws-sdk/client-s3`, `multer`, `formidable`.'
3
+ description: 'Read/write/delete files via the `storage` singleton — disks, drivers (local/S3/R2/DO Spaces), `storage.use(name)`, `StorageFile` handles, presigned URLs. Triggers: `storage.put`, `storage.get`, `storage.use`, `StorageFile`, `storageConfigurations`, `getPresignedUrl`, `getPresignedUploadUrl`; "save an uploaded file", "switch between local and S3", "generate a presigned URL", "read file metadata"; typical import `import { storage } from "@warlock.js/core"`. Skip: multipart parsing + image chain — the `upload-file` topic; image transforms — the `process-image` topic; storage config shape — the `configure-app` topic; competing libs `@aws-sdk/client-s3`, `multer`, `formidable`.'
4
4
  ---
5
5
 
6
6
  # Warlock — store a file
@@ -395,6 +395,6 @@ Client `PUT`s the bytes straight to R2 — your server never sees them.
395
395
 
396
396
  ## See also
397
397
 
398
- - [`configure-app/SKILL.md`](../configure-app/SKILL.md) — `src/config/storage.ts` shape and `env()` patterns.
399
- - [`warlock-conventions/SKILL.md`](../warlock-conventions/SKILL.md) — module layout for upload flows (`src/app/uploads/`).
400
- - [`send-response/SKILL.md`](../send-response/SKILL.md) — `response.sendFile(absPath)` for serving local files.
398
+ - The `configure-app` topic — `src/config/storage.ts` shape and `env()` patterns.
399
+ - The `warlock-conventions` topic — module layout for upload flows (`src/app/uploads/`).
400
+ - The `send-response` topic — `response.sendFile(absPath)` for serving local files.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: test-http
3
- description: 'Integration tests against a real HTTP server — `startHttpTestServer()` boots one shared server in globalSetup, then `testGet` / `testPost` / `expectJson` make typed requests against it. Triggers: `startHttpTestServer`, `startHttpTestServer({ port })`, `stopHttpTestServer`, `testGet`, `testPost`, `testPut`, `testPatch`, `testDelete`, `expectJson`, `getTestServerUrl`, `testRequest`, `PortInUseError`, `assertPortIsAvailable`, `isPortAvailable`; "integration-test a controller", "end-to-end HTTP test", "globalSetup HTTP server", "assert status and body shape", "test server port already in use", "EADDRINUSE while running tests", "run tests while the dev server is up"; typical import `import { testGet, testPost, expectJson } from "@warlock.js/core/tests"`. Skip: pure unit tests — `@warlock.js/core/test-service/SKILL.md`; controller shape — `@warlock.js/core/create-controller/SKILL.md`; competing libs `supertest`, `light-my-request`, `nock`.'
3
+ description: 'Integration tests against a real HTTP server — `startHttpTestServer()` boots one shared server in globalSetup, then `testGet` / `testPost` / `expectJson` make typed requests against it. Triggers: `startHttpTestServer`, `startHttpTestServer({ port })`, `stopHttpTestServer`, `testGet`, `testPost`, `testPut`, `testPatch`, `testDelete`, `expectJson`, `getTestServerUrl`, `testRequest`, `PortInUseError`, `assertPortIsAvailable`, `isPortAvailable`; "integration-test a controller", "end-to-end HTTP test", "globalSetup HTTP server", "assert status and body shape", "test server port already in use", "EADDRINUSE while running tests", "run tests while the dev server is up"; typical import `import { testGet, testPost, expectJson } from "@warlock.js/core/tests"`. Skip: pure unit tests — the `test-service` topic; controller shape — the `create-controller` topic; competing libs `supertest`, `light-my-request`, `nock`.'
4
4
  ---
5
5
 
6
6
  # Warlock — HTTP integration tests
@@ -350,7 +350,7 @@ This is fine for normal test flow. It bites when you're inside a transaction the
350
350
 
351
351
  ## See also
352
352
 
353
- - [`test-service/SKILL.md`](../test-service/SKILL.md) — pure unit tests against services/repositories/models (no HTTP).
354
- - [`create-controller/SKILL.md`](../create-controller/SKILL.md) — the controller shape your HTTP tests are exercising.
355
- - [`warlock-conventions/SKILL.md`](../warlock-conventions/SKILL.md) — module layout, where `tests/*.test.ts` files live.
356
- - [`write-cli-command/SKILL.md`](../write-cli-command/SKILL.md) — `warlock add test` scaffolds both global + worker setup files.
353
+ - The `test-service` topic — pure unit tests against services/repositories/models (no HTTP).
354
+ - The `create-controller` topic — the controller shape your HTTP tests are exercising.
355
+ - The `warlock-conventions` topic — module layout, where `tests/*.test.ts` files live.
356
+ - The `write-cli-command` topic — `warlock add test` scaffolds both global + worker setup files.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: test-service
3
- description: 'Pure unit tests against services, repositories, models, and use-cases — `setupTest({ connectors })` bootstraps the framework with its own DB/cache connections so you can call your code directly, and `teardownTest()` closes it. Triggers: `setupTest`, `teardownTest`, `src/test-setup.ts`, `tests.connectors`, `tests.setupTimeout`, `Application.setEnvironment`; "unit-test a service", "test a repository query", "vitest setupFiles", "skip connectors for pure-logic tests"; typical import `import { setupTest, teardownTest } from "@warlock.js/core/tests"`. Skip: HTTP integration — `@warlock.js/core/test-http/SKILL.md`; warlock add test scaffold — `@warlock.js/core/write-cli-command/SKILL.md`; competing tooling: jest direct, `supertest`, `nock`.'
3
+ description: 'Pure unit tests against services, repositories, models, and use-cases — `setupTest({ connectors })` bootstraps the framework with its own DB/cache connections so you can call your code directly, and `teardownTest()` closes it. Triggers: `setupTest`, `teardownTest`, `src/test-setup.ts`, `tests.connectors`, `tests.setupTimeout`, `Application.setEnvironment`; "unit-test a service", "test a repository query", "vitest setupFiles", "skip connectors for pure-logic tests"; typical import `import { setupTest, teardownTest } from "@warlock.js/core/tests"`. Skip: HTTP integration — the `test-http` topic; warlock add test scaffold — the `write-cli-command` topic; competing tooling: jest direct, `supertest`, `nock`.'
4
4
  ---
5
5
 
6
6
  # Warlock — test a service
@@ -151,7 +151,7 @@ export default defineConfig({
151
151
  });
152
152
  ```
153
153
 
154
- The `mongezVite()` plugin handles TypeScript path resolution and the framework's module shape. Without it, your imports break the moment vitest tries to load a Warlock module. `lowerStage3Decorators()` goes **first** — it lets decorated Cascade models (`@RegisterModel`, …) load under Vitest 4 / Vite 8; see [`@warlock.js/core/lower-stage3-decorators/SKILL.md`](@warlock.js/core/lower-stage3-decorators/SKILL.md).
154
+ The `mongezVite()` plugin handles TypeScript path resolution and the framework's module shape. Without it, your imports break the moment vitest tries to load a Warlock module. `lowerStage3Decorators()` goes **first** — it lets decorated Cascade models (`@RegisterModel`, …) load under Vitest 4 / Vite 8; see the `lower-stage3-decorators` topic.
155
155
 
156
156
  ### Keep Vitest setup out of development
157
157
 
@@ -391,9 +391,9 @@ In both cases the guard's scope matches the resource's scope, which is the point
391
391
 
392
392
  ## See also
393
393
 
394
- - [`test-http/SKILL.md`](../test-http/SKILL.md) — integration tests via the real HTTP server (`startHttpTestServer` + `testGet` / `testPost` / `expectJson`).
395
- - [`warlock-conventions/SKILL.md`](../warlock-conventions/SKILL.md) — where tests live in a module (`tests/*.test.ts`).
396
- - [`write-cli-command/SKILL.md`](../write-cli-command/SKILL.md) — `warlock add test` for the initial scaffold.
394
+ - The `test-http` topic — integration tests via the real HTTP server (`startHttpTestServer` + `testGet` / `testPost` / `expectJson`).
395
+ - The `warlock-conventions` topic — where tests live in a module (`tests/*.test.ts`).
396
+ - The `write-cli-command` topic — `warlock add test` for the initial scaffold.
397
397
 
398
398
  ## App modules and `importModule`
399
399
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: update-packages
3
- description: 'Keep a project current with `warlock update` — bump every `@warlock.js/*` dependency in package.json to its latest published version (range operator preserved), then run the lockfile-detected package manager install. Also covers the `warlock dev` update notice, its `u` update-and-restart keyboard shortcut, and the `devServer.checkForUpdates` toggle. Triggers: `warlock update`, `--no-install`, `--dry-run`, `--check`, `checkForUpdates`, `fetchLatestVersion`, `isNewerVersion`; "update warlock packages", "upgrade the framework", "is there a new warlock version", "update notice in the dev server", "press u to update", "dev server keyboard shortcut", "update check offline", "bump @warlock.js/* to latest"; typical CLI `warlock update`. Skip: dev/build/start runtime — `@warlock.js/core/run-app/SKILL.md`; writing a custom command — `@warlock.js/core/write-cli-command/SKILL.md`; installing a NEW feature package (auth, mail, storage) — that is `warlock add`; releasing/publishing the framework — workspace release tooling, not this command.'
3
+ description: 'Keep a project current with `warlock update` — bump every `@warlock.js/*` dependency in package.json to its latest published version (range operator preserved), then run the lockfile-detected package manager install. Also covers the `warlock dev` update notice, its `u` update-and-restart keyboard shortcut, and the `devServer.checkForUpdates` toggle. Triggers: `warlock update`, `--no-install`, `--dry-run`, `--check`, `checkForUpdates`, `fetchLatestVersion`, `isNewerVersion`; "update warlock packages", "upgrade the framework", "is there a new warlock version", "update notice in the dev server", "press u to update", "dev server keyboard shortcut", "update check offline", "bump @warlock.js/* to latest"; typical CLI `warlock update`. Skip: dev/build/start runtime — the `run-app` topic; writing a custom command — the `write-cli-command` topic; installing a NEW feature package (auth, mail, storage) — that is `warlock add`; releasing/publishing the framework — workspace release tooling, not this command.'
4
4
  ---
5
5
 
6
6
  # Warlock — update the framework
@@ -79,7 +79,7 @@ Pressing `u` on that notice runs the whole upgrade without leaving the dev serve
79
79
 
80
80
  1. The shortcut is disarmed and the terminal handed back, so the package manager owns stdin.
81
81
  2. Every `@warlock.js/*` dependency is rewritten to latest and installed — exactly what `warlock update` does.
82
- 3. The worker shuts down (freeing the http port) and exits `75`; the `warlock dev` supervisor spawns a replacement on the new version. See [`run-app/SKILL.md`](../run-app/SKILL.md) for the supervisor.
82
+ 3. The worker shuts down (freeing the http port) and exits `75`; the `warlock dev` supervisor spawns a replacement on the new version. See the `run-app` topic for the supervisor.
83
83
 
84
84
  What happens when it doesn't go to plan:
85
85
 
@@ -91,7 +91,7 @@ What happens when it doesn't go to plan:
91
91
 
92
92
  The shortcut is only offered when stdin is an interactive TTY. When it isn't (CI, piped stdin, a process supervisor), the notice falls back to the `Run npx warlock update` line instead — it never silently does nothing.
93
93
 
94
- `u` joins the dev server's standing shortcut bar (`r` restart, `c` clear, `q` quit, `h` help) — press `h` to list whatever is armed. See [`run-app/SKILL.md`](../run-app/SKILL.md) for the bar and the raw-mode / `Ctrl+C` contract.
94
+ `u` joins the dev server's standing shortcut bar (`r` restart, `c` clear, `q` quit, `h` help) — press `h` to list whatever is armed. See the `run-app` topic for the bar and the raw-mode / `Ctrl+C` contract.
95
95
 
96
96
  It is automatically skipped when:
97
97
 
@@ -128,6 +128,6 @@ Two small zero-dependency utilities back the tooling and are exported from `@war
128
128
 
129
129
  ## See also
130
130
 
131
- - [`run-app/SKILL.md`](../run-app/SKILL.md) — `warlock dev` / `build` / `start` and the `devServer.*` config knobs.
132
- - [`write-cli-command/SKILL.md`](../write-cli-command/SKILL.md) — author your own `warlock <cmd>`.
133
- - [`configure-app/SKILL.md`](../configure-app/SKILL.md) — `warlock.config.ts` shape and `defineConfig`.
131
+ - The `run-app` topic — `warlock dev` / `build` / `start` and the `devServer.*` config knobs.
132
+ - The `write-cli-command` topic — author your own `warlock <cmd>`.
133
+ - The `configure-app` topic — `warlock.config.ts` shape and `defineConfig`.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: upload-file
3
- description: 'Handle multipart file uploads — read via `request.file()` or `request.validated()`, validate with `v.file()`, save via `UploadedFile.save()` or the storage layer, transform images inline. Triggers: `UploadedFile`, `request.file`, `v.file`, `.save`, `.saveAs`, `.resize`, `.format`, `.quality`, `.image`, `.mimeType`, `.maxSize`; "accept a file upload", "validate file size and mime", "save to S3 or local disk", "resize an uploaded image on save"; typical import `import type { UploadedFile, RequestHandler } from "@warlock.js/core"`. Skip: storage drivers + presigned URLs — `@warlock.js/core/store-file/SKILL.md`; image-only transforms — `@warlock.js/core/process-image/SKILL.md`; schema rules — `@warlock.js/core/validate-input/SKILL.md`; competing libs `multer`, `formidable`, `busboy`.'
3
+ description: 'Handle multipart file uploads — read via `request.file()` or `request.validated()`, validate with `v.file()`, save via `UploadedFile.save()` or the storage layer, transform images inline. Triggers: `UploadedFile`, `request.file`, `v.file`, `.save`, `.saveAs`, `.resize`, `.format`, `.quality`, `.image`, `.mimeType`, `.maxSize`; "accept a file upload", "validate file size and mime", "save to S3 or local disk", "resize an uploaded image on save"; typical import `import type { UploadedFile, RequestHandler } from "@warlock.js/core"`. Skip: storage drivers + presigned URLs — the `store-file` topic; image-only transforms — the `process-image` topic; schema rules — the `validate-input` topic; competing libs `multer`, `formidable`, `busboy`.'
4
4
  ---
5
5
 
6
6
  # Warlock — upload a file
@@ -208,7 +208,7 @@ v.file() // must be UploadedFile
208
208
  .minHeight(200).maxHeight(4000);
209
209
  ```
210
210
 
211
- Size accepts either bytes (`.maxSize(5_242_880)`) or `{ unit, size }` (`{ unit: "MB", size: 5 }`). See [`validate-input`](../validate-input/SKILL.md) for the full validation pattern.
211
+ Size accepts either bytes (`.maxSize(5_242_880)`) or `{ unit, size }` (`{ unit: "MB", size: 5 }`). See the `validate-input` topic for the full validation pattern.
212
212
 
213
213
  ### Optional file field
214
214
 
@@ -291,7 +291,7 @@ await storage.use("s3").put(await uploadedFile.buffer(), "documents/report.pdf",
291
291
 
292
292
  ### Stream a download from a stored file
293
293
 
294
- The reverse direction — sending a stored file back via `response.sendFile(...)` is the cleanest path. For dynamic content, use `response.stream(...)`. See [`send-response`](../send-response/SKILL.md).
294
+ The reverse direction — sending a stored file back via `response.sendFile(...)` is the cleanest path. For dynamic content, use `response.stream(...)`. See the `send-response` topic.
295
295
 
296
296
  ## Gotchas
297
297
 
@@ -305,7 +305,7 @@ The reverse direction — sending a stored file back via `response.sendFile(...)
305
305
 
306
306
  ## See also
307
307
 
308
- - [`validate-input/SKILL.md`](../validate-input/SKILL.md) — `v.file()` rules and the validation pipeline.
309
- - [`create-controller/SKILL.md`](../create-controller/SKILL.md) — pulling files from `request.validated()` vs `request.file()`.
310
- - [`send-response/SKILL.md`](../send-response/SKILL.md) — `response.sendFile(...)` for serving the stored file back.
311
- - [`warlock-conventions/SKILL.md`](../warlock-conventions/SKILL.md) — storage configuration and driver selection.
308
+ - The `validate-input` topic — `v.file()` rules and the validation pipeline.
309
+ - The `create-controller` topic — pulling files from `request.validated()` vs `request.file()`.
310
+ - The `send-response` topic — `response.sendFile(...)` for serving the stored file back.
311
+ - The `warlock-conventions` topic — storage configuration and driver selection.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: use-app-context
3
- description: 'Read app-wide context — the `Application` static class (env, version, uptime, runtime strategy, boot lifecycle) plus the `app` runtime accessor (live Fastify, socket.io, router, database via the DI container). Triggers: `Application.isProduction`, `Application.environment`, `Application.runtimeStrategy`, `Application.uptime`, `Application.version`, `Application.onceBooted`, `Application.whenBooted`, `Application.isBooted`, `Application.onShutdown`, `Application.isShuttingDown`, `app.http`, `app.socket`, `app.database`, `app.router`; "branch on environment", "reach the live Fastify instance", "framework version in health endpoint", "dev vs production runtime check", "run code once the app is fully booted", "after all connectors started", "app booted hook", "run cleanup before shutdown", "graceful shutdown hook"; typical import `import { Application, app } from "@warlock.js/core"`. Skip: path helpers — `@warlock.js/core/resolve-path/SKILL.md`; connector start order — `@warlock.js/core/add-connector/SKILL.md`; competing patterns: bare `process.env.NODE_ENV`, ad-hoc Fastify imports.'
3
+ description: 'Read app-wide context — the `Application` static class (env, version, uptime, runtime strategy, boot lifecycle) plus the `app` runtime accessor (live Fastify, socket.io, router, database via the DI container). Triggers: `Application.isProduction`, `Application.environment`, `Application.runtimeStrategy`, `Application.uptime`, `Application.version`, `Application.onceBooted`, `Application.whenBooted`, `Application.isBooted`, `Application.onShutdown`, `Application.isShuttingDown`, `app.http`, `app.socket`, `app.database`, `app.router`; "branch on environment", "reach the live Fastify instance", "framework version in health endpoint", "dev vs production runtime check", "run code once the app is fully booted", "after all connectors started", "app booted hook", "run cleanup before shutdown", "graceful shutdown hook"; typical import `import { Application, app } from "@warlock.js/core"`. Skip: path helpers — the `resolve-path` topic; connector start order — the `add-connector` topic; competing patterns: bare `process.env.NODE_ENV`, ad-hoc Fastify imports.'
4
4
  ---
5
5
 
6
6
  # Warlock — use the application context
@@ -131,11 +131,11 @@ Application.onceBooted(() => {
131
131
 
132
132
  Hooks run **LIFO** (reverse of registration — last opened, first closed), each is awaited, and a throwing hook is caught + logged so it can't block the rest. `Application.isShuttingDown` flips `true` the moment shutdown begins — the built-in `/ready` endpoint reads it to report not-ready so a load balancer drains the instance first. Like `onceBooted`, registering after shutdown has begun runs the callback immediately.
133
133
 
134
- The framework triggers this for you (the connectors manager runs the hooks at the start of shutdown); app code only ever registers via `onShutdown`. For the HTTP-side story — `/health`, `/ready`, and graceful request draining — see `@warlock.js/core/health-checks/SKILL.md`.
134
+ The framework triggers this for you (the connectors manager runs the hooks at the start of shutdown); app code only ever registers via `onShutdown`. For the HTTP-side story — `/health`, `/ready`, and graceful request draining — see the `health-checks` topic.
135
135
 
136
136
  ## Paths
137
137
 
138
- For path helpers (`appPath`, `configPath`, `uploadsPath`, …) anchored at `process.cwd()`, the `paths.*` aggregate, and the `uploads.root` config override, see [`resolve-path/SKILL.md`](../resolve-path/SKILL.md).
138
+ For path helpers (`appPath`, `configPath`, `uploadsPath`, …) anchored at `process.cwd()`, the `paths.*` aggregate, and the `uploads.root` config override, see the `resolve-path` topic.
139
139
 
140
140
  The most-used helpers are also surfaced as no-argument getters on `Application`:
141
141
 
@@ -294,7 +294,7 @@ cors: {
294
294
 
295
295
  ## See also
296
296
 
297
- - [`resolve-path/SKILL.md`](../resolve-path/SKILL.md) — path helpers (`appPath`, `configPath`, `uploadsPath`, …) and the `paths.*` aggregate.
298
- - [`configure-app/SKILL.md`](../configure-app/SKILL.md) — `src/config/*.ts` and `warlock.config.ts`.
299
- - [`add-connector/SKILL.md`](../add-connector/SKILL.md) — using `Application.runtimeStrategy` inside a connector's `start()`.
300
- - [`warlock-conventions/SKILL.md`](../warlock-conventions/SKILL.md) — module layout, where paths point to.
297
+ - The `resolve-path` topic — path helpers (`appPath`, `configPath`, `uploadsPath`, …) and the `paths.*` aggregate.
298
+ - The `configure-app` topic — `src/config/*.ts` and `warlock.config.ts`.
299
+ - The `add-connector` topic — using `Application.runtimeStrategy` inside a connector's `start()`.
300
+ - The `warlock-conventions` topic — module layout, where paths point to.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: use-localization
3
- description: 'Multi-locale translations via `groupedTranslations` (declare keys), `t()` (look up; always use it in app code, never `request.t()`), `request.getLocaleCode()` (detect locale from headers/query), `getLocalized` (pick the right value from a localized-array column). Triggers: `groupedTranslations`, `t`, `request.t`, `request.trans`, `request.transFrom`, `request.getLocaleCode`, `request.setLocaleCode`, `getLocalized`; "add a translation key", "resolve a localized error message", "detect request locale", "pick the right per-locale column value"; typical import `import { t, getLocalized } from "@warlock.js/core"`. Skip: resource output — `@warlock.js/core/define-resource/SKILL.md`; module scaffold — `@warlock.js/core/create-module/SKILL.md`; competing libs `i18next`, `react-intl`, raw `@mongez/localization`.'
3
+ description: 'Multi-locale translations via `groupedTranslations` (declare keys), `t()` (look up; always use it in app code, never `request.t()`), `request.getLocaleCode()` (detect locale from headers/query), `getLocalized` (pick the right value from a localized-array column). Triggers: `groupedTranslations`, `t`, `request.t`, `request.trans`, `request.transFrom`, `request.getLocaleCode`, `request.setLocaleCode`, `getLocalized`; "add a translation key", "resolve a localized error message", "detect request locale", "pick the right per-locale column value"; typical import `import { t, getLocalized } from "@warlock.js/core"`. Skip: resource output — the `define-resource` topic; module scaffold — the `create-module` topic; competing libs `i18next`, `react-intl`, raw `@mongez/localization`.'
4
4
  ---
5
5
 
6
6
  # Warlock — translate keys + pick localized values
@@ -115,7 +115,7 @@ When an app uses `@warlock.js/web`, `warlock dev` writes `.warlock/typings/trans
115
115
  `useTrans()` now works correctly across hydration (5.15.0): the hydration
116
116
  payload ships a `translations` key with the active locale's keywords, and
117
117
  `@warlock.js/web` registers them into this same lookup table before the
118
- client hydrates — see `@warlock.js/web/write-the-root/SKILL.md`'s "`useTrans()`
118
+ client hydrates — see the `write-the-root` topic of the `warlock-js-web` skill's "`useTrans()`
119
119
  survives hydration" section for the failure this fixed.
120
120
 
121
121
  ### Locale on a specific lookup
@@ -316,10 +316,10 @@ GET /products/42?locale=ar
316
316
 
317
317
  ## See also
318
318
 
319
- - [`send-response/SKILL.md`](../send-response/SKILL.md) — error helpers that pair with translated messages (`response.notFound({ error: t("...") })`).
320
- - [`define-resource/SKILL.md`](../define-resource/SKILL.md) — using `getLocalized` inside resource output for clean per-locale responses.
321
- - [`create-module/SKILL.md`](../create-module/SKILL.md) — the `utils/locales.json` file is part of the generated module scaffold.
322
- - [`warlock-conventions/SKILL.md`](../warlock-conventions/SKILL.md) — `utils/locales.json` is auto-loaded; the suffix is mandatory.
319
+ - The `send-response` topic — error helpers that pair with translated messages (`response.notFound({ error: t("...") })`).
320
+ - The `define-resource` topic — using `getLocalized` inside resource output for clean per-locale responses.
321
+ - The `create-module` topic — the `utils/locales.json` file is part of the generated module scaffold.
322
+ - The `warlock-conventions` topic — `utils/locales.json` is auto-loaded; the suffix is mandatory.
323
323
 
324
324
  ## Route-owned web translations (5.17)
325
325
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: use-middleware
3
- description: 'Attach built-in HTTP middleware to routes via the `middleware` namespace from `@warlock.js/core` — rateLimit, concurrencyLimit, maxBodySize, idempotency, maintenance, ipFilter, cache. Plus `X-Request-Id` correlation, wired automatically. Triggers: `middleware.rateLimit`, `middleware.concurrencyLimit`, `middleware.maxBodySize`, `middleware.idempotency`, `middleware.maintenance`, `middleware.ipFilter`, `middleware.cache`, `X-Request-Id`, `Idempotency-Key`; "add rate limiting", "dedupe writes by idempotency key", "cap concurrent requests", "block IPs", "cache a GET response"; typical import `import { middleware } from "@warlock.js/core"`. Skip: author custom middleware — `@warlock.js/core/write-middleware/SKILL.md`; cache singleton — `@warlock.js/cache/cache-basics/SKILL.md`; competing libs `@fastify/rate-limit` direct, `express-rate-limit`, `helmet`.'
3
+ description: 'Attach built-in HTTP middleware to routes via the `middleware` namespace from `@warlock.js/core` — rateLimit, concurrencyLimit, maxBodySize, idempotency, maintenance, ipFilter, cache. Plus `X-Request-Id` correlation, wired automatically. Triggers: `middleware.rateLimit`, `middleware.concurrencyLimit`, `middleware.maxBodySize`, `middleware.idempotency`, `middleware.maintenance`, `middleware.ipFilter`, `middleware.cache`, `X-Request-Id`, `Idempotency-Key`; "add rate limiting", "dedupe writes by idempotency key", "cap concurrent requests", "block IPs", "cache a GET response"; typical import `import { middleware } from "@warlock.js/core"`. Skip: author custom middleware — the `write-middleware` topic; cache singleton — the `cache-basics` topic of the `warlock-js-cache` skill; competing libs `@fastify/rate-limit` direct, `express-rate-limit`, `helmet`.'
4
4
  ---
5
5
 
6
6
  # Warlock — use built-in middleware
@@ -16,7 +16,7 @@ middleware.maxBodySize("2mb");
16
16
  // ... etc
17
17
  ```
18
18
 
19
- For authoring your OWN middleware (custom guards, enrichment, etc.), see [`write-middleware`](../write-middleware/SKILL.md).
19
+ For authoring your OWN middleware (custom guards, enrichment, etc.), see the `write-middleware` topic.
20
20
 
21
21
  ## The catalog
22
22
 
@@ -268,7 +268,7 @@ export default {
268
268
 
269
269
  ## See also
270
270
 
271
- - [`write-middleware/SKILL.md`](../write-middleware/SKILL.md) — author your OWN middleware (custom guards, enrichment).
272
- - [`register-route/SKILL.md`](../register-route/SKILL.md) — where middleware attaches: `router.group` and route-options.
273
- - [`send-response/SKILL.md`](../send-response/SKILL.md) — the response helpers used to short-circuit (`tooManyRequests`, `contentTooLarge`, `serviceUnavailable`, etc.).
274
- - [`@warlock.js/cache/cache-basics/SKILL.md`](../../../cache/skills/cache-basics/SKILL.md) — the cache singleton (`@warlock.js/cache`) that backs `middleware.idempotency` and `middleware.cache`.
271
+ - The `write-middleware` topic — author your OWN middleware (custom guards, enrichment).
272
+ - The `register-route` topic — where middleware attaches: `router.group` and route-options.
273
+ - The `send-response` topic — the response helpers used to short-circuit (`tooManyRequests`, `contentTooLarge`, `serviceUnavailable`, etc.).
274
+ - The `cache-basics` topic of the `warlock-js-cache` skill — the cache singleton (`@warlock.js/cache`) that backs `middleware.idempotency` and `middleware.cache`.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: use-model-transformers
3
- description: 'Three schema-side helpers — `useHashedPassword()` (bcrypt on save) attaches via `.addTransformer(...)`; `useComputedSlug(field?, scope?)` (auto-slug from another field) and `useComputedModel(callback)` (arbitrary computed-on-save value) attach via `v.computed(...)`. Triggers: `useHashedPassword`, `useComputedSlug`, `useComputedModel`, `.addTransformer`, `v.computed`, `ComputedCallback`; "auto-hash a password field", "auto-slug from title on save", "derive a value at write time", "declarative model transformers"; typical import `import { useHashedPassword, useComputedSlug } from "@warlock.js/core"`. Skip: bcrypt setup details — `@warlock.js/core/hash-password/SKILL.md`; repository writes — `@warlock.js/core/use-repository/SKILL.md`; output filtering — `@warlock.js/core/define-resource/SKILL.md`; competing patterns: manual `await hashPassword(input)` in services, ORM lifecycle hooks.'
3
+ description: 'Three schema-side helpers — `useHashedPassword()` (bcrypt on save) attaches via `.addTransformer(...)`; `useComputedSlug(field?, scope?)` (auto-slug from another field) and `useComputedModel(callback)` (arbitrary computed-on-save value) attach via `v.computed(...)`. Triggers: `useHashedPassword`, `useComputedSlug`, `useComputedModel`, `.addTransformer`, `v.computed`, `ComputedCallback`; "auto-hash a password field", "auto-slug from title on save", "derive a value at write time", "declarative model transformers"; typical import `import { useHashedPassword, useComputedSlug } from "@warlock.js/core"`. Skip: bcrypt setup details — the `hash-password` topic; repository writes — the `use-repository` topic; output filtering — the `define-resource` topic; competing patterns: manual `await hashPassword(input)` in services, ORM lifecycle hooks.'
4
4
  ---
5
5
 
6
6
  # Warlock — declare model transformers
@@ -60,7 +60,7 @@ What it does at save time:
60
60
  | Existing row, password unchanged | Pass through (no re-hashing — stored hash preserved). |
61
61
  | Empty / undefined value | Pass through untouched. |
62
62
 
63
- Calls `authService.hashPassword(String(value))` under the hood — same bcryptjs path as the standalone `hashPassword()` helper. See [`hash-password/SKILL.md`](../hash-password/SKILL.md) for full bcrypt setup (salt rounds, `npm install bcryptjs`).
63
+ Calls `authService.hashPassword(String(value))` under the hood — same bcryptjs path as the standalone `hashPassword()` helper. See the `hash-password` topic for full bcrypt setup (salt rounds, `npm install bcryptjs`).
64
64
 
65
65
  ### Why declarative wins
66
66
 
@@ -214,7 +214,7 @@ Rule of thumb: transformers are for **pure, deterministic** transforms of the ro
214
214
 
215
215
  ## See also
216
216
 
217
- - [`hash-password/SKILL.md`](../hash-password/SKILL.md) — the bcrypt setup that `useHashedPassword` calls under the hood; salt rounds, `npm install bcryptjs`.
218
- - [`use-repository/SKILL.md`](../use-repository/SKILL.md) — where `create` / `save` calls happen that trigger the transformers.
219
- - [`define-resource/SKILL.md`](../define-resource/SKILL.md) — filtering transformed fields (`password`) out of API responses.
220
- - [`warlock-conventions/SKILL.md`](../warlock-conventions/SKILL.md) — schema files live in `src/app/<module>/models/<entity>/<entity>.model.ts`.
217
+ - The `hash-password` topic — the bcrypt setup that `useHashedPassword` calls under the hood; salt rounds, `npm install bcryptjs`.
218
+ - The `use-repository` topic — where `create` / `save` calls happen that trigger the transformers.
219
+ - The `define-resource` topic — filtering transformed fields (`password`) out of API responses.
220
+ - The `warlock-conventions` topic — schema files live in `src/app/<module>/models/<entity>/<entity>.model.ts`.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: use-repository
3
- description: 'Subclass `RepositoryManager` for data access — declare `source`, `filterBy`, `defaultOptions`, then call `list()`/`listCached()`/`find()`/`create()`/`update()`/`delete()`, the active/cached/cursor variants, and the `filterBy`-aware aggregates `sum()`/`avg()`/`min()`/`max()`/`groupBy()`/`aggregate()`. Triggers: `RepositoryManager`, `FilterRules`, `RepositoryOptions`, `.list`, `.listCached`, `.find`, `.findCached`, `.create`, `.update`, `.delete`, `.sum`, `.avg`, `.min`, `.max`, `.groupBy`, `.aggregate`, `simpleSelectColumns`; "create a repository", "filter rules for a list endpoint", "cursor vs page pagination", "cached vs uncached read", "sum/avg/group-by with filters"; typical import `import { RepositoryManager } from "@warlock.js/core"`. Skip: cache singleton — `@warlock.js/cache/cache-basics/SKILL.md`; use-case pipelines — `@warlock.js/core/write-use-case/SKILL.md`; wire mapping — `@warlock.js/core/define-resource/SKILL.md`; competing libs `typeorm` Repository, `prisma.client.<model>`, `@nestjs/typeorm`.'
3
+ description: 'Subclass `RepositoryManager` for data access — declare `source`, `filterBy`, `defaultOptions`, then call `list()`/`listCached()`/`find()`/`create()`/`update()`/`delete()`, the active/cached/cursor variants, and the `filterBy`-aware aggregates `sum()`/`avg()`/`min()`/`max()`/`groupBy()`/`aggregate()`. Triggers: `RepositoryManager`, `FilterRules`, `RepositoryOptions`, `.list`, `.listCached`, `.find`, `.findCached`, `.create`, `.update`, `.delete`, `.sum`, `.avg`, `.min`, `.max`, `.groupBy`, `.aggregate`, `simpleSelectColumns`; "create a repository", "filter rules for a list endpoint", "cursor vs page pagination", "cached vs uncached read", "sum/avg/group-by with filters"; typical import `import { RepositoryManager } from "@warlock.js/core"`. Skip: cache singleton — the `cache-basics` topic of the `warlock-js-cache` skill; use-case pipelines — the `write-use-case` topic; wire mapping — the `define-resource` topic; competing libs `typeorm` Repository, `prisma.client.<model>`, `@nestjs/typeorm`.'
4
4
  ---
5
5
 
6
6
  # Warlock — use a repository
@@ -422,9 +422,9 @@ The third arg is a context object — `{ allValues, dateFormat, ... }` — for f
422
422
 
423
423
  ## See also
424
424
 
425
- - [`create-module/SKILL.md`](../create-module/SKILL.md) — `warlock generate.repository` and where the file lives.
426
- - [`@warlock.js/cache/cache-basics/SKILL.md`](../../../cache/skills/cache-basics/SKILL.md) — the cache singleton behind `listCached` / `getCached`. See sibling skills (`pick-cache-driver`, `use-swr`) for related tasks.
427
- - [`write-use-case/SKILL.md`](../write-use-case/SKILL.md) — calling repositories from a use-case handler.
428
- - [`define-resource/SKILL.md`](../define-resource/SKILL.md) — mapping repository output to the wire format.
429
- - [`create-controller/SKILL.md`](../create-controller/SKILL.md) — services that consume repositories from the controller edge.
430
- - [`warlock-conventions/SKILL.md`](../warlock-conventions/SKILL.md) — controller → service → repository → model layering.
425
+ - The `create-module` topic — `warlock generate.repository` and where the file lives.
426
+ - The `cache-basics` topic of the `warlock-js-cache` skill — the cache singleton behind `listCached` / `getCached`. See sibling skills (`pick-cache-driver`, `use-swr`) for related tasks.
427
+ - The `write-use-case` topic — calling repositories from a use-case handler.
428
+ - The `define-resource` topic — mapping repository output to the wire format.
429
+ - The `create-controller` topic — services that consume repositories from the controller edge.
430
+ - The `warlock-conventions` topic — controller → service → repository → model layering.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: use-request-locals
3
- description: 'Carry typed, server-only data through one HTTP request with `request.locals`, usually written by middleware and read by downstream middleware or controllers. Augment `RequestLocals` in the module that owns each key; v5 no longer permits arbitrary `request.foo` properties. Triggers: `request.locals`, `RequestLocals`, `request.post`, `request.organization`, `Property does not exist on type Request`, `Request index signature`; "attach data to a request", "share middleware data with a controller", "type request locals", "migrate dynamic request properties"; typical type augmentation `declare module "@warlock.js/core" { interface RequestLocals { ... } }`. Skip: computed-on-demand single-flight values and removed `fromRequest` — `@warlock.js/core/request-memo/SKILL.md`; middleware mechanics — `@warlock.js/core/write-middleware/SKILL.md`; authenticated user typing — augment `RequestUser`, not `RequestLocals`; competing patterns: `(request as any).foo`, `request.set()`, module-global mutable state.'
3
+ description: 'Carry typed, server-only data through one HTTP request with `request.locals`, usually written by middleware and read by downstream middleware or controllers. Augment `RequestLocals` in the module that owns each key; v5 no longer permits arbitrary `request.foo` properties. Triggers: `request.locals`, `RequestLocals`, `request.post`, `request.organization`, `Property does not exist on type Request`, `Request index signature`; "attach data to a request", "share middleware data with a controller", "type request locals", "migrate dynamic request properties"; typical type augmentation `declare module "@warlock.js/core" { interface RequestLocals { ... } }`. Skip: computed-on-demand single-flight values and removed `fromRequest` — the `request-memo` topic; middleware mechanics — the `write-middleware` topic; authenticated user typing — augment `RequestUser`, not `RequestLocals`; competing patterns: `(request as any).foo`, `request.set()`, module-global mutable state.'
4
4
  ---
5
5
 
6
6
  # Warlock — use typed request locals
@@ -162,6 +162,6 @@ Writing `request.locals.organization` does not affect `request.all()`, `request.
162
162
 
163
163
  ## See also
164
164
 
165
- - [`request-memo/SKILL.md`](../request-memo/SKILL.md) — the `fromRequest()` migration and single-flight request memoization.
166
- - [`write-middleware/SKILL.md`](../write-middleware/SKILL.md) — middleware execution and registration.
167
- - [`create-controller/SKILL.md`](../create-controller/SKILL.md) — reading locals in downstream controllers.
165
+ - The `request-memo` topic — the `fromRequest()` migration and single-flight request memoization.
166
+ - The `write-middleware` topic — middleware execution and registration.
167
+ - The `create-controller` topic — reading locals in downstream controllers.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: validate-input
3
- description: 'Author seal schemas, attach them to controllers via `controller.validation = { schema }`, infer types via `Infer<typeof schema>`, and layer DB-aware (`unique`/`exists`) and file validators on top. Triggers: `v.object`, `v.string`, `v.email`, `Infer`, `controller.validation`, `.unique`, `.exists`, `uniqueExceptCurrentId`, `request.validated`; "validate a request body", "attach a schema to a controller", "DB-aware unique rule", "infer schema types"; typical import `import { v, type Infer } from "@warlock.js/seal"`. Skip: schema authoring foundations — `@warlock.js/seal/seal-basics/SKILL.md`; controller wiring — `@warlock.js/core/create-controller/SKILL.md`; file rules deep-dive — `@warlock.js/core/upload-file/SKILL.md`; competing libs `zod`, `joi`, `yup`, `class-validator`.'
3
+ description: 'Author seal schemas, attach them to controllers via `controller.validation = { schema }`, infer types via `Infer<typeof schema>`, and layer DB-aware (`unique`/`exists`) and file validators on top. Triggers: `v.object`, `v.string`, `v.email`, `Infer`, `controller.validation`, `.unique`, `.exists`, `uniqueExceptCurrentId`, `request.validated`; "validate a request body", "attach a schema to a controller", "DB-aware unique rule", "infer schema types"; typical import `import { v, type Infer } from "@warlock.js/seal"`. Skip: schema authoring foundations — the `seal-basics` topic of the `warlock-js-seal` skill; controller wiring — the `create-controller` topic; file rules deep-dive — the `upload-file` topic; competing libs `zod`, `joi`, `yup`, `class-validator`.'
4
4
  ---
5
5
 
6
6
  # Warlock — validate a request
@@ -73,7 +73,7 @@ From `@warlock.js/seal` — **always import from seal directly**. `@warlock.js/c
73
73
  | `v.literal(...values)` | exact literals | — |
74
74
  | `v.instanceof(Ctor, msg?)` | `Ctor` instances | — |
75
75
  | `v.lazy(() => schema)` | recursive/forward refs | — |
76
- | `v.file(msg?)` | `UploadedFile` | `.image()`, `.accept(exts)`, `.mimeType(types)`, `.minSize(n)`, `.maxSize(n)`, `.minWidth(n)`, `.maxWidth(n)` — see [`upload-file`](../upload-file/SKILL.md) |
76
+ | `v.file(msg?)` | `UploadedFile` | `.image()`, `.accept(exts)`, `.mimeType(types)`, `.minSize(n)`, `.maxSize(n)`, `.minWidth(n)`, `.maxWidth(n)` — see the `upload-file` topic |
77
77
  | `v.computed(callback)` | derived value | — |
78
78
  | `v.managed(callback)` | framework-injected value | — |
79
79
 
@@ -168,7 +168,7 @@ const uploadAvatarSchema = v.object({
168
168
  });
169
169
  ```
170
170
 
171
- Full file chain: `.image()`, `.accept(extensions)`, `.mimeType(types)`, `.pdf()`, `.excel()`, `.word()`, `.minSize(n)`, `.maxSize(n)`, `.minWidth(px)`, `.maxWidth(px)`, `.minHeight(px)`, `.maxHeight(px)`. See [`upload-file`](../upload-file/SKILL.md) for the full upload flow.
171
+ Full file chain: `.image()`, `.accept(extensions)`, `.mimeType(types)`, `.pdf()`, `.excel()`, `.word()`, `.minSize(n)`, `.maxSize(n)`, `.minWidth(px)`, `.maxWidth(px)`, `.minHeight(px)`, `.maxHeight(px)`. See the `upload-file` topic for the full upload flow.
172
172
 
173
173
  ### Optional file field
174
174
 
@@ -304,7 +304,7 @@ updateProductController.validation = {
304
304
 
305
305
  ## See also
306
306
 
307
- - [`create-controller/SKILL.md`](../create-controller/SKILL.md) — how the schema attaches and how `request.validated()` reads.
308
- - [`upload-file/SKILL.md`](../upload-file/SKILL.md) — `v.file()` and how it interacts with multipart uploads.
309
- - [`send-response/SKILL.md`](../send-response/SKILL.md) — the 400 helper used internally by `failedSchema`.
310
- - [`warlock-conventions/SKILL.md`](../warlock-conventions/SKILL.md) — `Request<Schema>` type-alias convention.
307
+ - The `create-controller` topic — how the schema attaches and how `request.validated()` reads.
308
+ - The `upload-file` topic — `v.file()` and how it interacts with multipart uploads.
309
+ - The `send-response` topic — the 400 helper used internally by `failedSchema`.
310
+ - The `warlock-conventions` topic — `Request<Schema>` type-alias convention.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: warlock-conventions
3
- description: 'Framework-wide invariants for projects built on @warlock.js/core — module layout, canonical imports, layered flow, file naming, and the non-negotiable rules every other warlock skill assumes. Triggers: `src/app/<module>`, `routes.ts`, `main.ts`, `Request<TSchema>`, `RequestHandler`, `GuardedRequestHandler`, `app/<module>/...`; "where do files go in this project", "canonical Warlock imports", "module layout rules", "controller-service-repository layering"; typical import `import { router, type RequestHandler } from "@warlock.js/core"`. Skip: scaffold a new module — `@warlock.js/core/create-module/SKILL.md`; route shape — `@warlock.js/core/register-route/SKILL.md`; controller shape — `@warlock.js/core/create-controller/SKILL.md`; competing patterns: `express` ad-hoc layouts, `@nestjs/common` decorator-driven structure.'
3
+ description: 'Framework-wide invariants for projects built on @warlock.js/core — module layout, canonical imports, layered flow, file naming, and the non-negotiable rules every other warlock skill assumes. Triggers: `src/app/<module>`, `routes.ts`, `main.ts`, `Request<TSchema>`, `RequestHandler`, `GuardedRequestHandler`, `app/<module>/...`; "where do files go in this project", "canonical Warlock imports", "module layout rules", "controller-service-repository layering"; typical import `import { router, type RequestHandler } from "@warlock.js/core"`. Skip: scaffold a new module — the `create-module` topic; route shape — the `register-route` topic; controller shape — the `create-controller` topic; competing patterns: `express` ad-hoc layouts, `@nestjs/common` decorator-driven structure.'
4
4
  ---
5
5
 
6
6
  # Warlock — framework-wide conventions
@@ -124,14 +124,14 @@ Within the same module, use relative paths (`./`, `../`).
124
124
 
125
125
  ## Type augmentations
126
126
 
127
- `src/typings.d.ts` is the project's module-augmentation file. It ships with the scaffold, is listed explicitly in `tsconfig.json`'s `include`, and is where application-wide `declare module "@warlock.js/core"` blocks live — `RequestLocals` and `RequestUser` are already there as empty interfaces. Keep its trailing `export {}` (without it the block declares an ambient module and erases the framework's real typings) and keep the augmented declarations as `interface`, the one sanctioned exception to this project's prefer-`type` rule, since declaration merging is interface-only. See [`use-request-locals`](../use-request-locals/SKILL.md).
127
+ `src/typings.d.ts` is the project's module-augmentation file. It ships with the scaffold, is listed explicitly in `tsconfig.json`'s `include`, and is where application-wide `declare module "@warlock.js/core"` blocks live — `RequestLocals` and `RequestUser` are already there as empty interfaces. Keep its trailing `export {}` (without it the block declares an ambient module and erases the framework's real typings) and keep the augmented declarations as `interface`, the one sanctioned exception to this project's prefer-`type` rule, since declaration merging is interface-only. See the `use-request-locals` topic.
128
128
 
129
129
  ## Decorators
130
130
 
131
- Cascade uses `@RegisterModel()` for the model registry and `@BelongsTo` / `@HasMany` / `@MorphTo` for relations. The scaffolded `tsconfig.json` has `"experimentalDecorators": false` — these are native Stage-3 decorators, not legacy. Never set that flag to `true`; see [`lower-stage3-decorators`](../lower-stage3-decorators/SKILL.md).
131
+ Cascade uses `@RegisterModel()` for the model registry and `@BelongsTo` / `@HasMany` / `@MorphTo` for relations. The scaffolded `tsconfig.json` has `"experimentalDecorators": false` — these are native Stage-3 decorators, not legacy. Never set that flag to `true`; see the `lower-stage3-decorators` topic.
132
132
 
133
133
  ## See also
134
134
 
135
- - [`register-route/SKILL.md`](../register-route/SKILL.md) — how to wire URLs to controllers.
136
- - [`create-controller/SKILL.md`](../create-controller/SKILL.md) — controller signature, validation, response shape.
137
- - [`send-response/SKILL.md`](../send-response/SKILL.md) — the full Response helper surface.
135
+ - The `register-route` topic — how to wire URLs to controllers.
136
+ - The `create-controller` topic — controller signature, validation, response shape.
137
+ - The `send-response` topic — the full Response helper surface.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: warlock-doctor
3
- description: 'Run `warlock doctor` — a read-only diagnostics command that checks routes / config / connectors / optional-peers / health endpoints / release hygiene and prints a pass/warn/fail report, exiting non-zero on any failure. Add your own probe with the `DoctorCheck` contract and `runChecks` / `formatReportLines`. Triggers: `warlock doctor`, `doctorCommand`, `DoctorCheck`, `CheckResult`, `CheckStatus`, `DoctorReport`, `runChecks`, `formatReportLines`, `printReport`, `defaultDoctorChecks`; "diagnose my app", "preflight / preflight check", "is the app healthy", "why are there 0 routes", "pre-release sanity check", "CI smoke check"; run as `npx warlock doctor`. Skip: the live `/health` + `/ready` HTTP probes — `@warlock.js/core/health-checks/SKILL.md`; authoring a general CLI command — `@warlock.js/core/write-cli-command/SKILL.md`; releasing the package — `releasing-warlock-monorepo`; competing tools `npm doctor`, `nest info`, hand-rolled preflight scripts.'
3
+ description: 'Run `warlock doctor` — a read-only diagnostics command that checks routes / config / connectors / optional-peers / health endpoints / release hygiene and prints a pass/warn/fail report, exiting non-zero on any failure. Add your own probe with the `DoctorCheck` contract and `runChecks` / `formatReportLines`. Triggers: `warlock doctor`, `doctorCommand`, `DoctorCheck`, `CheckResult`, `CheckStatus`, `DoctorReport`, `runChecks`, `formatReportLines`, `printReport`, `defaultDoctorChecks`; "diagnose my app", "preflight / preflight check", "is the app healthy", "why are there 0 routes", "pre-release sanity check", "CI smoke check"; run as `npx warlock doctor`. Skip: the live `/health` + `/ready` HTTP probes — the `health-checks` topic; authoring a general CLI command — the `write-cli-command` topic; releasing the package — `releasing-warlock-monorepo`; competing tools `npm doctor`, `nest info`, hand-rolled preflight scripts.'
4
4
  ---
5
5
 
6
6
  # Warlock — `warlock doctor`
@@ -132,7 +132,7 @@ A `⚠ routes: 0 routes registered` line is the tell that a route module threw o
132
132
 
133
133
  ## See also
134
134
 
135
- - [`health-checks/SKILL.md`](../health-checks/SKILL.md) — the live `/health` + `/ready` HTTP probes and the `health` registry the `health` doctor check reports on.
136
- - [`write-cli-command/SKILL.md`](../write-cli-command/SKILL.md) — authoring a command + its `preload` plan, the shape `doctorCommand` is built from.
137
- - [`add-connector/SKILL.md`](../add-connector/SKILL.md) — connector registration, which the `connectors` check enumerates.
138
- - [`warlock-conventions/SKILL.md`](../warlock-conventions/SKILL.md) — project layout the checks assume.
135
+ - The `health-checks` topic — the live `/health` + `/ready` HTTP probes and the `health` registry the `health` doctor check reports on.
136
+ - The `write-cli-command` topic — authoring a command + its `preload` plan, the shape `doctorCommand` is built from.
137
+ - The `add-connector` topic — connector registration, which the `connectors` check enumerates.
138
+ - The `warlock-conventions` topic — project layout the checks assume.
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: warlock-routes
3
- description: 'Run `warlock routes` — a read-only command that lists the registered HTTP routes as a verb-colored table (method / path / name / action / middleware-count / source), a sibling of `warlock doctor`. Filter with `--method` / `--path` / `--name`, or emit normalized rows as JSON with `--json`. Also covers `warlock routes:diff`, which compares live page routes against the last `warlock build`''s route snapshot and exits non-zero on drift. Triggers: `warlock routes`, `routesCommand`, `warlock routes:diff`, `routesDiffCommand`, "list my routes", "show all routes", "route table", "what endpoints does my app expose", "dump routes as JSON", "which routes have middleware", "route map for CI", "did my page routes drift from the last build"; run as `npx warlock routes` / `npx warlock routes:diff`. Skip: read-only health/preflight checks — `@warlock.js/core/warlock-doctor/SKILL.md`; defining/naming/grouping routes — `@warlock.js/core/register-route/SKILL.md`; authoring a general CLI command — `@warlock.js/core/write-cli-command/SKILL.md`; competing tools `nest`/`express` route listers, `php artisan route:list`.'
3
+ description: 'Run `warlock routes` — a read-only command that lists the registered HTTP routes as a verb-colored table (method / path / name / action / middleware-count / source), a sibling of `warlock doctor`. Filter with `--method` / `--path` / `--name`, or emit normalized rows as JSON with `--json`. Also covers `warlock routes:diff`, which compares live page routes against the last `warlock build`''s route snapshot and exits non-zero on drift. Triggers: `warlock routes`, `routesCommand`, `warlock routes:diff`, `routesDiffCommand`, "list my routes", "show all routes", "route table", "what endpoints does my app expose", "dump routes as JSON", "which routes have middleware", "route map for CI", "did my page routes drift from the last build"; run as `npx warlock routes` / `npx warlock routes:diff`. Skip: read-only health/preflight checks — the `warlock-doctor` topic; defining/naming/grouping routes — the `register-route` topic; authoring a general CLI command — the `write-cli-command` topic; competing tools `nest`/`express` route listers, `php artisan route:list`.'
4
4
  ---
5
5
 
6
6
  # Warlock — `warlock routes`
7
7
 
8
- `warlock routes` lists every registered HTTP route as a table. It's the read-only sibling of [`warlock doctor`](../warlock-doctor/SKILL.md): it boots the app far enough to register route modules — but **starts no connectors**, so it never opens a database, cache, or socket connection.
8
+ `warlock routes` lists every registered HTTP route as a table. It's the read-only sibling of the `warlock-doctor` topic: it boots the app far enough to register route modules — but **starts no connectors**, so it never opens a database, cache, or socket connection.
9
9
 
10
10
  ```bash
11
11
  npx warlock routes
@@ -123,7 +123,7 @@ and exits non-zero.
123
123
 
124
124
  ## See also
125
125
 
126
- - [`warlock-doctor/SKILL.md`](../warlock-doctor/SKILL.md) — the read-only diagnostics sibling; its `routes` check warns when this table would be empty.
127
- - [`register-route/SKILL.md`](../register-route/SKILL.md) — defining, naming, and grouping the routes this command lists.
128
- - [`run-app/SKILL.md`](../run-app/SKILL.md) — `warlock build`, the command that produces the snapshot `routes:diff` compares against.
129
- - [`write-cli-command/SKILL.md`](../write-cli-command/SKILL.md) — the command + `preload` shape `routesCommand` is built from.
126
+ - The `warlock-doctor` topic — the read-only diagnostics sibling; its `routes` check warns when this table would be empty.
127
+ - The `register-route` topic — defining, naming, and grouping the routes this command lists.
128
+ - The `run-app` topic — `warlock build`, the command that produces the snapshot `routes:diff` compares against.
129
+ - The `write-cli-command` topic — the command + `preload` shape `routesCommand` is built from.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: wire-socket
3
- description: 'Configure Socket.IO via `src/config/socket.ts`, reach the live server through `getSocketServer()` (or `app.socket` post-bootstrap), register `connection` handlers once the late-phase socket connector has booted, emit from controllers/services, use rooms and namespaces. Triggers: `app.socket`, `getSocketServer`, `SocketOptions`, `socket.io` `Server`, `socket.join`, `socket.to`, `io.of`, `io.use`; "add realtime chat", "emit socket events from a service", "use rooms and namespaces", "per-socket JWT auth". Skip: connector lifecycle — `@warlock.js/core/add-connector/SKILL.md`; app context accessors — `@warlock.js/core/use-app-context/SKILL.md`; competing libs `ws`, `socket.io` direct without Warlock connector, `uWebSockets.js`.'
3
+ description: 'Configure Socket.IO via `src/config/socket.ts`, reach the live server through `getSocketServer()` (or `app.socket` post-bootstrap), register `connection` handlers once the late-phase socket connector has booted, emit from controllers/services, use rooms and namespaces. Triggers: `app.socket`, `getSocketServer`, `SocketOptions`, `socket.io` `Server`, `socket.join`, `socket.to`, `io.of`, `io.use`; "add realtime chat", "emit socket events from a service", "use rooms and namespaces", "per-socket JWT auth". Skip: connector lifecycle — the `add-connector` topic; app context accessors — the `use-app-context` topic; competing libs `ws`, `socket.io` direct without Warlock connector, `uWebSockets.js`.'
4
4
  ---
5
5
 
6
6
  # Warlock — wire a Socket.IO server
@@ -283,6 +283,6 @@ CLI commands, scheduled jobs, queue workers — anything running outside an HTTP
283
283
 
284
284
  ## See also
285
285
 
286
- - [`use-app-context/SKILL.md`](../use-app-context/SKILL.md) — `app.socket` runtime accessor + `Application` static metadata.
287
- - [`add-connector/SKILL.md`](../add-connector/SKILL.md) — how connectors order their boot sequence around your modules.
288
- - [`warlock-conventions/SKILL.md`](../warlock-conventions/SKILL.md) — where socket-related code lives (a setup function for handler registration, `services/` for emit sites).
286
+ - The `use-app-context` topic — `app.socket` runtime accessor + `Application` static metadata.
287
+ - The `add-connector` topic — how connectors order their boot sequence around your modules.
288
+ - The `warlock-conventions` topic — where socket-related code lives (a setup function for handler registration, `services/` for emit sites).