@stacksjs/defaults 0.72.103 → 0.73.1

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 (163) hide show
  1. package/ai/AGENTS.md +25 -4
  2. package/ai/README.md +26 -4
  3. package/ai/skills/stacks-actions/SKILL.md +1 -1
  4. package/ai/skills/stacks-ai/SKILL.md +1 -1
  5. package/ai/skills/stacks-alias/SKILL.md +1 -1
  6. package/ai/skills/stacks-analytics/SKILL.md +1 -1
  7. package/ai/skills/stacks-api/SKILL.md +1 -1
  8. package/ai/skills/stacks-arrays/SKILL.md +1 -1
  9. package/ai/skills/stacks-auto-imports/SKILL.md +1 -1
  10. package/ai/skills/stacks-browse/SKILL.md +1 -1
  11. package/ai/skills/stacks-browser/SKILL.md +1 -1
  12. package/ai/skills/stacks-buddy/SKILL.md +1 -1
  13. package/ai/skills/stacks-build/SKILL.md +79 -5
  14. package/ai/skills/stacks-cache/SKILL.md +1 -1
  15. package/ai/skills/stacks-calendar/SKILL.md +1 -1
  16. package/ai/skills/stacks-chat/SKILL.md +1 -1
  17. package/ai/skills/stacks-cli/SKILL.md +1 -1
  18. package/ai/skills/stacks-cloud/SKILL.md +1 -1
  19. package/ai/skills/stacks-cms/SKILL.md +1 -1
  20. package/ai/skills/stacks-codebase-design/DEEPENING.md +79 -0
  21. package/ai/skills/stacks-codebase-design/DESIGN-IT-TWICE.md +72 -0
  22. package/ai/skills/stacks-codebase-design/SKILL.md +180 -0
  23. package/ai/skills/stacks-collections/SKILL.md +1 -1
  24. package/ai/skills/stacks-commerce/SKILL.md +141 -35
  25. package/ai/skills/stacks-composables/SKILL.md +1 -1
  26. package/ai/skills/stacks-config/SKILL.md +1 -1
  27. package/ai/skills/stacks-configuration/SKILL.md +1 -1
  28. package/ai/skills/stacks-cron/SKILL.md +1 -1
  29. package/ai/skills/stacks-crosswind/SKILL.md +1 -1
  30. package/ai/skills/stacks-database/SKILL.md +1 -1
  31. package/ai/skills/stacks-datetime/SKILL.md +1 -1
  32. package/ai/skills/stacks-dependencies/SKILL.md +1 -1
  33. package/ai/skills/stacks-deploy/SKILL.md +1 -1
  34. package/ai/skills/stacks-desktop/SKILL.md +1 -1
  35. package/ai/skills/stacks-development/SKILL.md +1 -1
  36. package/ai/skills/stacks-dns/SKILL.md +1 -1
  37. package/ai/skills/stacks-docs/SKILL.md +1 -1
  38. package/ai/skills/stacks-domain-modeling/FORMATS.md +123 -0
  39. package/ai/skills/stacks-domain-modeling/SKILL.md +109 -0
  40. package/ai/skills/stacks-enums/SKILL.md +1 -1
  41. package/ai/skills/stacks-error-handling/SKILL.md +1 -1
  42. package/ai/skills/stacks-events/SKILL.md +1 -1
  43. package/ai/skills/stacks-faker/SKILL.md +1 -1
  44. package/ai/skills/stacks-flow/PHASE-BOUNDARIES.md +91 -0
  45. package/ai/skills/stacks-flow/SKILL.md +117 -0
  46. package/ai/skills/stacks-git/SKILL.md +37 -9
  47. package/ai/skills/stacks-grilling/SKILL.md +85 -0
  48. package/ai/skills/stacks-guard/SKILL.md +86 -11
  49. package/ai/skills/stacks-guard/scripts/block-destructive.sh +67 -0
  50. package/ai/skills/stacks-handoff/SKILL.md +70 -0
  51. package/ai/skills/stacks-health/SKILL.md +1 -1
  52. package/ai/skills/stacks-http/SKILL.md +1 -1
  53. package/ai/skills/stacks-i18n/SKILL.md +1 -1
  54. package/ai/skills/stacks-investigate/SKILL.md +234 -106
  55. package/ai/skills/stacks-investigate/scripts/hitl-loop.template.sh +47 -0
  56. package/ai/skills/stacks-jobs/SKILL.md +1 -1
  57. package/ai/skills/stacks-listeners/SKILL.md +1 -1
  58. package/ai/skills/stacks-logging/SKILL.md +1 -1
  59. package/ai/skills/stacks-mail/SKILL.md +1 -1
  60. package/ai/skills/stacks-middleware/SKILL.md +1 -1
  61. package/ai/skills/stacks-migrations/SKILL.md +1 -1
  62. package/ai/skills/stacks-models/SKILL.md +1 -1
  63. package/ai/skills/stacks-new-feature/SKILL.md +65 -5
  64. package/ai/skills/stacks-notifications/SKILL.md +1 -1
  65. package/ai/skills/stacks-objects/SKILL.md +1 -1
  66. package/ai/skills/stacks-office-hours/SKILL.md +16 -2
  67. package/ai/skills/stacks-orm/SKILL.md +1 -1
  68. package/ai/skills/stacks-path/SKILL.md +1 -1
  69. package/ai/skills/stacks-payments/SKILL.md +35 -1
  70. package/ai/skills/stacks-plan-review/SKILL.md +27 -6
  71. package/ai/skills/stacks-plugins/SKILL.md +1 -1
  72. package/ai/skills/stacks-prototype/LOGIC.md +103 -0
  73. package/ai/skills/stacks-prototype/SKILL.md +66 -0
  74. package/ai/skills/stacks-prototype/UI.md +112 -0
  75. package/ai/skills/stacks-push/SKILL.md +1 -1
  76. package/ai/skills/stacks-query-builder/SKILL.md +1 -1
  77. package/ai/skills/stacks-queue/SKILL.md +1 -1
  78. package/ai/skills/stacks-realtime/SKILL.md +1 -1
  79. package/ai/skills/stacks-registry/SKILL.md +1 -1
  80. package/ai/skills/stacks-repl/SKILL.md +1 -1
  81. package/ai/skills/stacks-retro/SKILL.md +121 -75
  82. package/ai/skills/stacks-review/SKILL.md +182 -74
  83. package/ai/skills/stacks-router/SKILL.md +1 -1
  84. package/ai/skills/stacks-routes/SKILL.md +1 -1
  85. package/ai/skills/stacks-scaffolding/SKILL.md +1 -1
  86. package/ai/skills/stacks-scheduler/SKILL.md +1 -1
  87. package/ai/skills/stacks-search-engine/SKILL.md +1 -1
  88. package/ai/skills/stacks-security/SKILL.md +1 -1
  89. package/ai/skills/stacks-security-audit/SKILL.md +1 -1
  90. package/ai/skills/stacks-server/SKILL.md +1 -1
  91. package/ai/skills/stacks-shell/SKILL.md +1 -1
  92. package/ai/skills/stacks-slug/SKILL.md +1 -1
  93. package/ai/skills/stacks-sms/SKILL.md +1 -1
  94. package/ai/skills/stacks-socials/SKILL.md +1 -1
  95. package/ai/skills/stacks-storage/SKILL.md +1 -1
  96. package/ai/skills/stacks-strings/SKILL.md +1 -1
  97. package/ai/skills/stacks-stx/SKILL.md +1 -1
  98. package/ai/skills/stacks-tdd/EXAMPLES.md +136 -0
  99. package/ai/skills/stacks-tdd/SKILL.md +125 -0
  100. package/ai/skills/stacks-testing/SKILL.md +13 -3
  101. package/ai/skills/stacks-tunnel/SKILL.md +1 -1
  102. package/ai/skills/stacks-types/SKILL.md +1 -1
  103. package/ai/skills/stacks-ui/SKILL.md +1 -1
  104. package/ai/skills/stacks-utils/SKILL.md +1 -1
  105. package/ai/skills/stacks-validation/SKILL.md +1 -1
  106. package/ai/skills/stacks-whois/SKILL.md +1 -1
  107. package/ai/skills/stacks-wizard/SKILL.md +127 -0
  108. package/ai/skills/stacks-wizard/scripts/template.sh +208 -0
  109. package/ai/skills/stacks-writing-for-agents/MECHANICS.md +125 -0
  110. package/ai/skills/stacks-writing-for-agents/SKILL.md +218 -0
  111. package/app/Actions/Auth/GenerateTwoFactorSecretAction.ts +12 -2
  112. package/app/Actions/Commerce/Shipping/{DriverDestroyAction.ts → CourierDestroyAction.ts} +6 -6
  113. package/app/Actions/Commerce/Shipping/{DriverIndexAction.ts → CourierIndexAction.ts} +3 -3
  114. package/app/Actions/Commerce/Shipping/CourierPingStoreAction.ts +61 -0
  115. package/app/Actions/Commerce/Shipping/{DriverShowAction.ts → CourierShowAction.ts} +5 -5
  116. package/app/Actions/Commerce/Shipping/{DriverStoreAction.ts → CourierStoreAction.ts} +4 -4
  117. package/app/Actions/Commerce/Shipping/{DriverUpdateAction.ts → CourierUpdateAction.ts} +6 -6
  118. package/app/Actions/Commerce/Shipping/DeliveryRouteStartAction.ts +38 -0
  119. package/app/Actions/Commerce/Shipping/DeliveryStopCompleteAction.ts +40 -0
  120. package/app/Actions/Commerce/Shipping/DeliveryStopFailAction.ts +44 -0
  121. package/app/Actions/Commerce/Shipping/DeliveryStopStartAction.ts +39 -0
  122. package/app/Actions/Commerce/Shipping/courier-session.ts +75 -0
  123. package/app/Actions/Commerce/commerce-action.test.ts +5 -5
  124. package/app/Actions/Dashboard/Commerce/CommerceDeliveryAction.ts +5 -5
  125. package/app/Actions/Dashboard/Commerce/CourierIndexAction.ts +24 -0
  126. package/app/Actions/Dashboard/Commerce/DeliveryRouteIndexAction.ts +7 -7
  127. package/app/Actions/Dashboard/Commerce/commerce-delivery.test.ts +11 -11
  128. package/app/Actions/Dashboard/Commerce/commerce-delivery.ts +29 -29
  129. package/app/Actions/Dashboard/Commerce/{driver-records.test.ts → courier-records.test.ts} +9 -9
  130. package/app/Actions/Dashboard/Commerce/{driver-records.ts → courier-records.ts} +14 -14
  131. package/app/Actions/Dashboard/Commerce/delivery-route-records.test.ts +13 -13
  132. package/app/Actions/Dashboard/Commerce/delivery-route-records.ts +25 -25
  133. package/app/Models/User.ts +1 -1
  134. package/app/Models/commerce/{Driver.ts → Courier.ts} +7 -7
  135. package/app/Models/commerce/{DriverPing.ts → CourierPing.ts} +7 -7
  136. package/app/Models/commerce/DeliveryRoute.ts +6 -6
  137. package/app/Models/commerce/DeliveryStop.ts +31 -8
  138. package/bootstrap.ts +7 -0
  139. package/functions/commerce/shippings/couriers.ts +19 -0
  140. package/ide/vscode/package.json +1 -1
  141. package/package.json +4 -3
  142. package/resources/components/Dashboard/Commerce/Delivery/{DriverDeleteDialog.stx → CourierDeleteDialog.stx} +5 -5
  143. package/resources/components/Dashboard/Commerce/Delivery/{DriverDialog.stx → CourierDialog.stx} +10 -10
  144. package/resources/components/Dashboard/Commerce/Delivery/{DriversDashboard.stx → CouriersDashboard.stx} +43 -43
  145. package/resources/components/Dashboard/Commerce/Delivery/{DriversTable.stx → CouriersTable.stx} +21 -21
  146. package/resources/components/Dashboard/Commerce/Delivery/DeliveryOverviewDashboard.stx +18 -18
  147. package/resources/components/Dashboard/Commerce/Delivery/DeliveryRouteDeleteDialog.stx +2 -2
  148. package/resources/components/Dashboard/Commerce/Delivery/DeliveryRouteDialog.stx +22 -22
  149. package/resources/components/Dashboard/Commerce/Delivery/DeliveryRoutesDashboard.stx +24 -24
  150. package/resources/components/Dashboard/Commerce/Delivery/DeliveryRoutesTable.stx +8 -8
  151. package/resources/components/Dashboard/Commerce/Delivery/TabNavigation.stx +1 -1
  152. package/resources/functions/dashboard/data.ts +1 -1
  153. package/resources/functions/dashboard/sidebar.ts +2 -2
  154. package/routes/dashboard-api.ts +6 -6
  155. package/routes/dashboard.ts +7 -7
  156. package/routes/delivery.ts +24 -0
  157. package/types/defaults.ts +3 -3
  158. package/views/dashboard/.discovered-models.json +18 -18
  159. package/views/dashboard/AUDIT.md +1 -1
  160. package/views/dashboard/commerce/delivery/{drivers.stx → couriers.stx} +2 -2
  161. package/views/dashboard/composables/useChart.ts +16 -2
  162. package/app/Actions/Dashboard/Commerce/DriverIndexAction.ts +0 -24
  163. package/functions/commerce/shippings/drivers.ts +0 -19
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-slug
3
- description: Use when generating URL slugs in Stacks — creating unique slugs with database collision detection, the uniqueSlug function with table/column configuration, or basic slugification. Covers @stacksjs/slug.
3
+ description: Use when generating URL slugs in Stacks - creating unique slugs with database collision detection, the uniqueSlug function with table/column configuration, or basic slugification. Covers @stacksjs/slug.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-sms
3
- description: Use when implementing SMS in Stacks — sending text messages, the SmsBuilder fluent API, SMS templates, phone verification (OTP/2FA), bulk sending, Twilio/Vonage drivers, E.164 formatting, or the SMS facade. Covers @stacksjs/sms and config/sms.ts.
3
+ description: Use when implementing SMS in Stacks - sending text messages, the SmsBuilder fluent API, SMS templates, phone verification (OTP/2FA), bulk sending, Twilio/Vonage drivers, E.164 formatting, or the SMS facade. Covers @stacksjs/sms and config/sms.ts.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-socials
3
- description: Use when implementing social authentication in Stacks — OAuth2 flows with GitHub/Google/Facebook/Twitter providers, the AbstractProvider base class, PKCE support, state management, scope configuration, social user profiles, or token handling. Covers @stacksjs/socials.
3
+ description: Use when implementing social authentication in Stacks - OAuth2 flows with GitHub/Google/Facebook/Twitter providers, the AbstractProvider base class, PKCE support, state management, scope configuration, social user profiles, or token handling. Covers @stacksjs/socials.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-storage
3
- description: Use when working with file storage in Stacks — the Storage facade (put/get/delete/copy/move/list), StorageAdapter interface, local and S3 disk configurations, file uploads (UploadedFile class), file operations (read/write/copy/move/delete/hash/glob/zip), visibility management, checksums, MIME types, temporary URLs, or filesystem configuration. Covers @stacksjs/storage and config/filesystems.ts.
3
+ description: Use when working with file storage in Stacks - the Storage facade (put/get/delete/copy/move/list), StorageAdapter interface, local and S3 disk configurations, file uploads (UploadedFile class), file operations (read/write/copy/move/delete/hash/glob/zip), visibility management, checksums, MIME types, temporary URLs, or filesystem configuration. Covers @stacksjs/storage and config/filesystems.ts.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-strings
3
- description: Use when working with string utilities in Stacks — case conversion (camelCase, PascalCase, snake_case, kebab-case, CONSTANT_CASE, Train-Case, etc.), pluralization, string validation (email, URL, UUID, credit card, etc.), slug generation, random strings, template interpolation, or the Str facade. Covers @stacksjs/strings.
3
+ description: Use when working with string utilities in Stacks - case conversion (camelCase, PascalCase, snake_case, kebab-case, CONSTANT_CASE, Train-Case, etc.), pluralization, string validation (email, URL, UUID, credit card, etc.), slug generation, random strings, template interpolation, or the Str facade. Covers @stacksjs/strings.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-stx
3
- description: Use when working with STX templates in a Stacks application — template syntax, components, directives, signals, reactivity, SSR, streaming, hydration, or debugging STX rendering. STX is the ONLY templating system for Stacks.
3
+ description: Use when working with STX templates in a Stacks application - template syntax, components, directives, signals, reactivity, SSR, streaming, hydration, or debugging STX rendering. STX is the ONLY templating system for Stacks.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -0,0 +1,136 @@
1
+ # Good and bad tests
2
+
3
+ ## Good
4
+
5
+ **Integration-style**: through real interfaces, not mocks of internal parts.
6
+
7
+ ```typescript
8
+ import { describe, expect, test } from 'bun:test'
9
+
10
+ test('a customer can check out with a valid cart', async () => {
11
+ const cart = await Cart.create({ customer_id: customer.id })
12
+ await cart.add(product)
13
+
14
+ const result = await checkout(cart, paymentMethod)
15
+
16
+ expect(result.status).toBe('confirmed')
17
+ })
18
+ ```
19
+
20
+ Characteristics:
21
+
22
+ - Tests behaviour callers care about.
23
+ - Uses the public surface only.
24
+ - Survives internal refactors.
25
+ - Describes what, not how.
26
+ - One logical assertion per test.
27
+
28
+ ## Bad
29
+
30
+ **Implementation-detail tests**: coupled to internal structure.
31
+
32
+ ```typescript
33
+ // bad: asserts on an internal collaborator
34
+ test('checkout calls the payment driver', async () => {
35
+ const spy = mock(paymentDriver.process)
36
+ await checkout(cart, payment)
37
+ expect(spy).toHaveBeenCalledWith(cart.total)
38
+ })
39
+ ```
40
+
41
+ Red flags: mocking internal collaborators, testing private methods, asserting on
42
+ call counts or ordering, a test that breaks on a refactor with no behaviour
43
+ change, a test name that describes how.
44
+
45
+ ```typescript
46
+ // bad: bypasses the interface to verify
47
+ test('createUser saves to the database', async () => {
48
+ await createUser({ name: 'Alice' })
49
+ const row = await db.raw('select * from users where name = ?', ['Alice'])
50
+ expect(row).toBeDefined()
51
+ })
52
+
53
+ // good: verifies through the interface
54
+ test('createUser makes the user retrievable', async () => {
55
+ const user = await createUser({ name: 'Alice' })
56
+ const retrieved = await User.find(user.id)
57
+ expect(retrieved?.name).toBe('Alice')
58
+ })
59
+ ```
60
+
61
+ **Tautological tests**: the expected value restates the implementation, so the
62
+ test passes by construction.
63
+
64
+ ```typescript
65
+ // bad: expected value recomputed the way the code computes it
66
+ test('calculateTotal sums line items', () => {
67
+ const items = [{ price: 10 }, { price: 5 }]
68
+ const expected = items.reduce((sum, i) => sum + i.price, 0)
69
+ expect(calculateTotal(items)).toBe(expected)
70
+ })
71
+
72
+ // good: expected value is an independent literal
73
+ test('calculateTotal sums line items', () => {
74
+ expect(calculateTotal([{ price: 10 }, { price: 5 }])).toBe(15)
75
+ })
76
+ ```
77
+
78
+ ## When to stand something in
79
+
80
+ Stand in at **system boundaries** only:
81
+
82
+ - Third-party HTTP: Stripe, SES, SendGrid, Mailgun, Twilio, Anthropic, OpenAI,
83
+ Meilisearch, Algolia, Route53.
84
+ - Time and randomness.
85
+ - The queue, when the assertion is "this job was dispatched" rather than "this
86
+ job ran".
87
+ - The filesystem, sometimes. The local storage driver is usually enough.
88
+
89
+ Do not stand in for:
90
+
91
+ - Your own actions, models, jobs or listeners.
92
+ - The database. Use `setupDatabase()` and `refreshDatabase()`.
93
+ - The cache. Use the `memory` driver.
94
+ - Anything under `@stacksjs/*` that you control.
95
+
96
+ ## Designing for a stand-in
97
+
98
+ **Accept the dependency.**
99
+
100
+ ```typescript
101
+ // easy to substitute
102
+ export async function processPayment(order: Order, gateway: PaymentGateway) {
103
+ return gateway.charge(order.total)
104
+ }
105
+
106
+ // hard to substitute
107
+ export async function processPayment(order: Order) {
108
+ const gateway = new StripeGateway(env.STRIPE_KEY)
109
+ return gateway.charge(order.total)
110
+ }
111
+ ```
112
+
113
+ **Prefer an SDK-shaped surface over one generic fetcher.** A named function per
114
+ external operation is independently substitutable and self-documenting. One
115
+ `fetch(endpoint, options)` forces conditional logic into every stand-in. This is
116
+ the shape the framework's own driver packages use, so a new external integration
117
+ should copy it rather than invent a third pattern.
118
+
119
+ ## Queue assertions
120
+
121
+ ```typescript
122
+ import { fake, restore } from '@stacksjs/queue'
123
+
124
+ test('publishing an article dispatches the index job', async () => {
125
+ const queue = fake()
126
+
127
+ await publishArticle(article.id)
128
+
129
+ queue.assertDispatched('IndexArticle')
130
+ restore()
131
+ })
132
+ ```
133
+
134
+ `fake()` mutates global state, so `restore()` belongs in the same test or in
135
+ `afterEach`. A suite that forgets it will fail somewhere else and blame the wrong
136
+ code.
@@ -0,0 +1,125 @@
1
+ ---
2
+ name: stacks-tdd
3
+ description: Use when building a feature or fixing a bug test-first in a Stacks project, when the user mentions red-green-refactor or vertical slices, or when deciding which seam a test belongs at. Covers the red-green loop over bun test and @stacksjs/testing, seam selection, and the test anti-patterns.
4
+ license: MIT
5
+ compatibility: Bun >= 1.3.0, TypeScript
6
+ allowed-tools: Read Edit Write Bash Grep Glob
7
+ ---
8
+
9
+ # Test-driven development
10
+
11
+ TDD is the red to green loop. This skill is the reference that makes the loop
12
+ produce tests worth keeping: what a good test is, where tests go, the
13
+ anti-patterns, and the rules of the loop. Every section applies on every cycle.
14
+ Consult them before and during, not after.
15
+
16
+ `stacks-testing` is the *mechanics*: `setupDatabase()`, `refreshDatabase()`,
17
+ DynamoDB Local, `bunfig.toml` preload, the CLI flags. This skill is the
18
+ *discipline*. Read that one for the API and this one for the decisions.
19
+
20
+ Credit: adapted from Matt Pocock's `tdd` skill (MIT),
21
+ <https://github.com/mattpocock/skills>.
22
+
23
+ ## What a good test is
24
+
25
+ Tests verify behaviour through public interfaces, never implementation details.
26
+ Code can change entirely, tests should not. A good test reads like a
27
+ specification: "a customer can check out with a valid cart" tells you exactly
28
+ what capability exists, and it survives refactors because it does not care about
29
+ internal structure.
30
+
31
+ See [EXAMPLES.md](EXAMPLES.md) for good and bad tests side by side, and for
32
+ where mocking is legitimate.
33
+
34
+ ## Seams: where tests go
35
+
36
+ A **seam** is the public boundary you test at, the interface where you observe
37
+ behaviour without reaching inside. Tests live at seams, never against internals.
38
+ When the shape of that interface is itself in question, call the Skill tool with
39
+ `stacks-codebase-design` for the vocabulary. It owns the module, interface,
40
+ depth, seam, adapter, leverage and locality terms.
41
+
42
+ **Test only at pre-agreed seams.** Before writing any test, write down the seams
43
+ under test and confirm them with the user. No test is written at an unconfirmed
44
+ seam. You cannot test everything, so agreeing the seams up front is how testing
45
+ effort lands on the critical paths instead of on every edge case.
46
+
47
+ A Stacks app has four seams worth naming, from highest to lowest. Prefer the
48
+ highest one that can go red on the behaviour you care about:
49
+
50
+ | Seam | Test through | Use when |
51
+ |---|---|---|
52
+ | Route | an HTTP request against the running route, middleware included | the behaviour is a user-visible endpoint |
53
+ | Action | calling the action in `app/Actions/` directly | the behaviour is the request-to-response logic, and you do not need middleware in the picture |
54
+ | Model | the model's query and mutation surface, against the test database | the behaviour is a trait, a relationship, a computed attribute, or a validation rule |
55
+ | Function | a plain import from `resources/functions/` or a `@stacksjs/*` package | the behaviour is pure computation |
56
+
57
+ The fewer seams you cross for one feature, the better. One is ideal.
58
+
59
+ ## The database is not a boundary to mock
60
+
61
+ The framework hands you a real one. `setupDatabase()` creates
62
+ `database/stacks_testing.sqlite`, `refreshDatabase()` drops and re-migrates it,
63
+ and the per-attribute `factory` functions in each model produce realistic rows.
64
+ Use them. A test that mocks `User.find()` is testing the mock.
65
+
66
+ Real boundaries in a Stacks app, the ones where a stand-in is correct: third
67
+ party HTTP (Stripe, SES, Anthropic, Meilisearch), the clock, randomness, and the
68
+ queue when you are asserting that a job was dispatched rather than that it ran.
69
+ `fake()` / `restore()` from `@stacksjs/queue` exist for that last one.
70
+
71
+ ## Anti-patterns
72
+
73
+ - **Implementation-coupled**: mocks internal collaborators, tests private
74
+ methods, or verifies through a side channel (querying the database with raw
75
+ SQL instead of reading back through the model). The tell: the test breaks when
76
+ you refactor but behaviour has not changed.
77
+ - **Tautological**: the assertion recomputes the expected value the way the code
78
+ does, so it passes by construction and can never disagree with the code.
79
+ Expected values must come from an independent source of truth: a known-good
80
+ literal, a worked example, the spec.
81
+ - **Horizontal slicing**: writing all the tests first, then all the
82
+ implementation. Bulk tests verify *imagined* behaviour. You test the shape of
83
+ things rather than user-facing behaviour, the tests go insensitive to real
84
+ changes, and you commit to a test structure before understanding the
85
+ implementation. Work in **vertical slices** instead: one test, one
86
+ implementation, repeat. Each test is a **tracer bullet** that responds to what
87
+ the last cycle taught you.
88
+ - **Leaking state between files**: `refreshDatabase()` drops every table, and
89
+ `fake()` mutates global queue state. Both belong in setup and teardown, never
90
+ mid-test.
91
+
92
+ ## Rules of the loop
93
+
94
+ - **Red before green.** Write the failing test first, then only enough code to
95
+ pass it. Do not anticipate future tests or add speculative features.
96
+ - **One slice at a time.** One seam, one test, one minimal implementation per
97
+ cycle.
98
+ - **Run the narrow thing during the loop.** `bun test tests/feature/articles.test.ts`
99
+ is the loop. `buddy test` is the gate you run once at the end. Passing a path
100
+ to `bun test` filters, it does not scope, so keep the path narrow while you
101
+ iterate.
102
+ - **Typecheck alongside.** `./buddy typecheck` for `app/`, `config/`,
103
+ `resources/` and `routes/`. It runs on tsgo and finishes in seconds, so there
104
+ is no reason to save it for the end.
105
+ - **Refactoring is not part of the loop.** It belongs to review. Run
106
+ `/stacks-review` once the slice is green.
107
+
108
+ ## Model-first order
109
+
110
+ A vertical slice in Stacks cuts through the model, the migration, the action, the
111
+ route and the test. Migrations are derived from models here, so the loop has one
112
+ extra beat compared to other frameworks:
113
+
114
+ ```
115
+ model change → buddy generate:migrations → review the SQL → buddy migrate → red test → green
116
+ ```
117
+
118
+ Skipping the review step is how a wrong column type reaches every downstream
119
+ environment. See `stacks-new-feature` for the full slice and
120
+ `stacks-migrations` for the generation rules.
121
+
122
+ ## Downstream
123
+
124
+ > Green? Run `/stacks-review` for the two-axis review, then `/stacks-browse` if
125
+ > the slice has a UI.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-testing
3
- description: Use when writing or running tests in Stacks — test setup, database test utilities (setup, refresh, truncate), DynamoDB testing, feature test patterns, the test CLI commands, test configuration in bunfig.toml, or test environment setup. Covers @stacksjs/testing and tests/.
3
+ description: Use when writing or running tests in Stacks - test setup, database test utilities (setup, refresh, truncate), DynamoDB testing, feature test patterns, the test CLI commands, test configuration in bunfig.toml, or test environment setup. Covers @stacksjs/testing and tests/.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -10,6 +10,11 @@ allowed-tools: Read Edit Write Bash Grep Glob
10
10
 
11
11
  Uses Bun's built-in test runner with Stacks-specific test utilities.
12
12
 
13
+ This skill is the **mechanics**: the utilities, the setup, the CLI, the gotchas.
14
+ `stacks-tdd` is the **discipline**: the red-green loop, which seam a test belongs
15
+ at, and the anti-patterns that make a test worse than no test. Read that one
16
+ before deciding what to test, and this one for how.
17
+
13
18
  ## Key Paths
14
19
  - Core package: `storage/framework/core/testing/src/`
15
20
  - Test directory: `tests/`
@@ -122,8 +127,13 @@ preload = ["./tests/setup.ts"]
122
127
  - Uses Bun's native test runner, NOT Jest or Vitest
123
128
  - Test preload runs `tests/setup.ts` before each test file
124
129
  - SQLite testing database is at `database/stacks_testing.sqlite`
125
- - `refreshDatabase()` drops ALL tables — use in test setup only
130
+ - `refreshDatabase()` drops ALL tables - use in test setup only
126
131
  - DynamoDB Local must be installed for DynamoDB tests
127
- - Queue testing uses `fake()`/`restore()` pattern — affects global state
132
+ - Queue testing uses `fake()`/`restore()` pattern - affects global state
128
133
  - `@stacksjs/faker` provides test data generation
129
134
  - Coverage reports with `bun run test:coverage`
135
+
136
+ ## Downstream
137
+
138
+ > Deciding what to test, or where? `/stacks-tdd`. Reviewing someone else's
139
+ > tests? `/stacks-review` audits coverage as its third pass.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-tunnel
3
- description: Use when setting up tunnels in Stacks — local development tunnels for webhook testing, custom cloud tunnel deployment to AWS EC2, tunnel event callbacks (onConnect, onRequest, onResponse, onError), subdomain configuration, or the buddy share command. Covers @stacksjs/tunnel.
3
+ description: Use when setting up tunnels in Stacks - local development tunnels for webhook testing, custom cloud tunnel deployment to AWS EC2, tunnel event callbacks (onConnect, onRequest, onResponse, onError), subdomain configuration, or the buddy share command. Covers @stacksjs/tunnel.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-types
3
- description: Use when working with TypeScript type definitions in a Stacks application — model types, request types, environment variables, event types, billing types, attribute types, or auto-imported globals. Covers storage/framework/types/ and storage/framework/core/types/src/.
3
+ description: Use when working with TypeScript type definitions in a Stacks application - model types, request types, environment variables, event types, billing types, attribute types, or auto-imported globals. Covers storage/framework/types/ and storage/framework/core/types/src/.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-ui
3
- description: Use when working with UI in a Stacks application — components, composables, reactivity (refs/watch/computed), Craft native components, Crosswind CSS, Crosswind utility framework, accessibility, or the STX templating engine. Covers @stacksjs/ui, @stacksjs/stx, and related UI tooling.
3
+ description: Use when working with UI in a Stacks application - components, composables, reactivity (refs/watch/computed), Craft native components, Crosswind CSS, Crosswind utility framework, accessibility, or the STX templating engine. Covers @stacksjs/ui, @stacksjs/stx, and related UI tooling.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-utils
3
- description: Use when needing general utility functions in Stacks — deep merge, debounce/throttle, color output, byte formatting, markdown tables, YAML parsing, Pipeline class, ResizeObserver, Macroable, project initialization, indentation detection, or the comprehensive utility toolkit. Covers @stacksjs/utils.
3
+ description: Use when needing general utility functions in Stacks - deep merge, debounce/throttle, color output, byte formatting, markdown tables, YAML parsing, Pipeline class, ResizeObserver, Macroable, project initialization, indentation detection, or the comprehensive utility toolkit. Covers @stacksjs/utils.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-validation
3
- description: Use when implementing validation in Stacks — type guards (isString, isNumber, isBoolean, isObject, isArray, isFunction, etc.), numeric checks (isPositive, isEven, isInteger), the schema builder for model attribute validation, or request validation. Covers @stacksjs/validation.
3
+ description: Use when implementing validation in Stacks - type guards (isString, isNumber, isBoolean, isObject, isArray, isFunction, etc.), numeric checks (isPositive, isEven, isInteger), the schema builder for model attribute validation, or request validation. Covers @stacksjs/validation.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-whois
3
- description: Use when performing WHOIS lookups in Stacks — domain queries, batch lookups, SOCKS proxy support, TLD server discovery, response parsing, the WhoIsParser class, or the built-in SocksClient. Covers @stacksjs/whois.
3
+ description: Use when performing WHOIS lookups in Stacks - domain queries, batch lookups, SOCKS proxy support, TLD server discovery, response parsing, the WhoIsParser class, or the built-in SocksClient. Covers @stacksjs/whois.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -0,0 +1,127 @@
1
+ ---
2
+ name: stacks-wizard
3
+ description: Use when a procedure needs a human in the loop and the agent has hit a wall it cannot pass alone - provisioning cloud credentials, verifying a sending domain, setting CI secrets, clicking through a registrar or third-party dashboard, or running a one-off cutover. Generates an interactive bash wizard that opens each URL, captures each value, and writes it into .env and GitHub secrets.
4
+ license: MIT
5
+ compatibility: Bun >= 1.3.0, TypeScript, bash
6
+ allowed-tools: Read Edit Write Bash Grep Glob
7
+ ---
8
+
9
+ # Wizard
10
+
11
+ A **wizard** is a bash script that walks a human, step by step, through a manual
12
+ procedure that is tedious to do by hand and tedious to re-explain to an agent
13
+ every time. It opens each URL, says exactly what to click and copy, captures the
14
+ values, writes them where they belong, confirms before anything irreversible, and
15
+ shows how many stages are left.
16
+
17
+ The UX is already solved by [scripts/template.sh](scripts/template.sh):
18
+ stage-by-stage progress, confirmation gates, cross-platform URL opening including
19
+ WSL, hidden entry for secrets, idempotent `.env` upserts, `gh secret` and
20
+ `gh variable` writes, and a closing summary. **Your job is only to scope the
21
+ procedure and author its stages.** Everything above the `STAGES` marker is
22
+ identical in every wizard, and that consistency is the point. Never hand-edit it.
23
+
24
+ A wizard is ephemeral by default: built for one run, saved to a scratch path or
25
+ `scripts/`, deleted when the job is done. Commit it only when the user wants a
26
+ repeatable setup path that should live in the repo.
27
+
28
+ Credit: adapted from Matt Pocock's `wizard` skill (MIT),
29
+ <https://github.com/mattpocock/skills>. The template library is his, unchanged
30
+ except for the example stage.
31
+
32
+ ## When this is the right tool
33
+
34
+ Reach for it the moment you hit a step only the human can take. In a Stacks
35
+ project that is a short and predictable list:
36
+
37
+ - **AWS access** for `buddy deploy` and `buddy cloud`, and the IAM permissions
38
+ behind them.
39
+ - **Domains and DNS**: `buddy domains:purchase`, registrar nameserver changes,
40
+ the delegation that has to happen at the registrar rather than in Route53.
41
+ - **Email**: SES domain verification, DKIM records, moving out of the sandbox,
42
+ the port 25 request.
43
+ - **CI secrets**: every `secrets.*` and `vars.*` reference in
44
+ `.github/workflows/*` is a value the wizard should produce.
45
+ - **Server provisioning**: a Hetzner or other provider token, an SSH key added to
46
+ the account, the first-boot steps.
47
+ - **Payments**: Stripe keys and webhook endpoints.
48
+
49
+ If the agent could just do it itself, it should. This is for where a human is
50
+ genuinely in the loop.
51
+
52
+ ## Process
53
+
54
+ ### 1. Scope the procedure
55
+
56
+ Work out every manual step the human must take and every value captured along the
57
+ way. Read the repo first, do not ask cold:
58
+
59
+ - `.env`, `.env.example`, `.env.*`, and `config/services.ts` for what the app
60
+ already expects.
61
+ - `config/cloud.ts`, `config/dns.ts`, `config/email.ts` for what the deploy
62
+ targets.
63
+ - `.github/workflows/*` for every secret and variable CI reads.
64
+ - The relevant skill (`stacks-deploy`, `stacks-cloud`, `stacks-dns`,
65
+ `stacks-email`) for which steps the CLI already automates, so the wizard covers
66
+ only the gap.
67
+
68
+ Then show the user the ordered list of stages and the values each produces, and
69
+ confirm. They may add, drop or reorder.
70
+
71
+ **Done when** every stage is named in order, and for each captured value you know
72
+ (a) where the human gets it, (b) where it is written (`.env`, a GitHub secret,
73
+ both, or nowhere, since some stages are pure actions), and (c) whether it is
74
+ secret and so needs hidden entry.
75
+
76
+ ### 2. Map each stage's journey
77
+
78
+ For each stage, write the precise path a human follows: which URL to open, what
79
+ to do there, where the value is shown, which variable it fills. For example
80
+ "Route53 console, Hosted zones, pick the domain, copy the four NS records".
81
+
82
+ Where you do not know the current UI or the exact command, say so and ask the
83
+ user or check the docs. Never invent steps that may not exist.
84
+
85
+ **Done when** every stage traces to concrete instructions a stranger could
86
+ follow.
87
+
88
+ ### 3. Author the wizard
89
+
90
+ Copy `scripts/template.sh` to the target path. Replace the example stage with one
91
+ `stage` per step, in dependency order. Set `TOTAL_STAGES` to the number you
92
+ wrote. Use the library helpers: `stage`, `say`, `step`, `note`, `warn`,
93
+ `open_url`, `ask`, `ask_secret`, `write_env`, `set_secret`, `set_var`, `pause`,
94
+ `confirm`.
95
+
96
+ Hold the bar the template sets:
97
+
98
+ - Open the URL before asking for its value.
99
+ - `ask_secret` for anything secret.
100
+ - `write_env` every persisted value.
101
+ - `set_secret` only the values CI actually needs.
102
+ - `confirm` before anything irreversible.
103
+ - One focused task per `stage`, because each stage clears the screen and anything
104
+ the human still needs must not have scrolled away.
105
+
106
+ In a Stacks project, finish with a stage that encrypts what you just wrote:
107
+ `./buddy env:encrypt`, and for a production file the matching
108
+ `buddy env:keypair` / `buddy env:rotate` step. A wizard that leaves plaintext
109
+ credentials in `.env.production` has done half a job. `buddy env:check` is the
110
+ verification line for the closing stage.
111
+
112
+ ### 4. Verify and hand off
113
+
114
+ - `bash -n <script>`, and `shellcheck` if it is available.
115
+ - `chmod +x <script>`.
116
+ - Do not run it end to end yourself. It opens browsers and blocks on human input.
117
+ Trace it statically instead: every value from step 1 is captured and lands
118
+ where step 1 said, and every `set_secret` name matches a `secrets.*` reference
119
+ in CI exactly.
120
+ - Tell the user how to run it. If it is a repeatable setup path, commit it under
121
+ `scripts/` and link it from the README so the next person runs the script
122
+ instead of asking an agent.
123
+
124
+ ## Downstream
125
+
126
+ > Credentials in place? `/stacks-deploy` for the deploy workflow itself, and
127
+ > `/stacks-guard` before anything touches production.