@stacksjs/defaults 0.72.102 → 0.73.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.
- package/ai/AGENTS.md +25 -4
- package/ai/README.md +26 -4
- package/ai/skills/stacks-actions/SKILL.md +1 -1
- package/ai/skills/stacks-ai/SKILL.md +1 -1
- package/ai/skills/stacks-alias/SKILL.md +1 -1
- package/ai/skills/stacks-analytics/SKILL.md +1 -1
- package/ai/skills/stacks-api/SKILL.md +1 -1
- package/ai/skills/stacks-arrays/SKILL.md +1 -1
- package/ai/skills/stacks-auto-imports/SKILL.md +1 -1
- package/ai/skills/stacks-browse/SKILL.md +1 -1
- package/ai/skills/stacks-browser/SKILL.md +1 -1
- package/ai/skills/stacks-buddy/SKILL.md +1 -1
- package/ai/skills/stacks-build/SKILL.md +79 -5
- package/ai/skills/stacks-cache/SKILL.md +1 -1
- package/ai/skills/stacks-calendar/SKILL.md +1 -1
- package/ai/skills/stacks-chat/SKILL.md +1 -1
- package/ai/skills/stacks-cli/SKILL.md +1 -1
- package/ai/skills/stacks-cloud/SKILL.md +1 -1
- package/ai/skills/stacks-cms/SKILL.md +1 -1
- package/ai/skills/stacks-codebase-design/DEEPENING.md +79 -0
- package/ai/skills/stacks-codebase-design/DESIGN-IT-TWICE.md +72 -0
- package/ai/skills/stacks-codebase-design/SKILL.md +180 -0
- package/ai/skills/stacks-collections/SKILL.md +1 -1
- package/ai/skills/stacks-commerce/SKILL.md +141 -35
- package/ai/skills/stacks-composables/SKILL.md +1 -1
- package/ai/skills/stacks-config/SKILL.md +1 -1
- package/ai/skills/stacks-configuration/SKILL.md +1 -1
- package/ai/skills/stacks-cron/SKILL.md +1 -1
- package/ai/skills/stacks-crosswind/SKILL.md +1 -1
- package/ai/skills/stacks-database/SKILL.md +1 -1
- package/ai/skills/stacks-datetime/SKILL.md +1 -1
- package/ai/skills/stacks-dependencies/SKILL.md +1 -1
- package/ai/skills/stacks-deploy/SKILL.md +1 -1
- package/ai/skills/stacks-desktop/SKILL.md +1 -1
- package/ai/skills/stacks-development/SKILL.md +1 -1
- package/ai/skills/stacks-dns/SKILL.md +1 -1
- package/ai/skills/stacks-docs/SKILL.md +1 -1
- package/ai/skills/stacks-domain-modeling/FORMATS.md +123 -0
- package/ai/skills/stacks-domain-modeling/SKILL.md +109 -0
- package/ai/skills/stacks-enums/SKILL.md +1 -1
- package/ai/skills/stacks-error-handling/SKILL.md +1 -1
- package/ai/skills/stacks-events/SKILL.md +1 -1
- package/ai/skills/stacks-faker/SKILL.md +1 -1
- package/ai/skills/stacks-flow/PHASE-BOUNDARIES.md +91 -0
- package/ai/skills/stacks-flow/SKILL.md +117 -0
- package/ai/skills/stacks-git/SKILL.md +37 -9
- package/ai/skills/stacks-grilling/SKILL.md +85 -0
- package/ai/skills/stacks-guard/SKILL.md +86 -11
- package/ai/skills/stacks-guard/scripts/block-destructive.sh +67 -0
- package/ai/skills/stacks-handoff/SKILL.md +70 -0
- package/ai/skills/stacks-health/SKILL.md +1 -1
- package/ai/skills/stacks-http/SKILL.md +1 -1
- package/ai/skills/stacks-i18n/SKILL.md +1 -1
- package/ai/skills/stacks-investigate/SKILL.md +234 -106
- package/ai/skills/stacks-investigate/scripts/hitl-loop.template.sh +47 -0
- package/ai/skills/stacks-jobs/SKILL.md +1 -1
- package/ai/skills/stacks-listeners/SKILL.md +1 -1
- package/ai/skills/stacks-logging/SKILL.md +1 -1
- package/ai/skills/stacks-mail/SKILL.md +1 -1
- package/ai/skills/stacks-middleware/SKILL.md +1 -1
- package/ai/skills/stacks-migrations/SKILL.md +1 -1
- package/ai/skills/stacks-models/SKILL.md +1 -1
- package/ai/skills/stacks-new-feature/SKILL.md +65 -5
- package/ai/skills/stacks-notifications/SKILL.md +1 -1
- package/ai/skills/stacks-objects/SKILL.md +1 -1
- package/ai/skills/stacks-office-hours/SKILL.md +16 -2
- package/ai/skills/stacks-orm/SKILL.md +1 -1
- package/ai/skills/stacks-path/SKILL.md +1 -1
- package/ai/skills/stacks-payments/SKILL.md +35 -1
- package/ai/skills/stacks-plan-review/SKILL.md +27 -6
- package/ai/skills/stacks-plugins/SKILL.md +1 -1
- package/ai/skills/stacks-prototype/LOGIC.md +103 -0
- package/ai/skills/stacks-prototype/SKILL.md +66 -0
- package/ai/skills/stacks-prototype/UI.md +112 -0
- package/ai/skills/stacks-push/SKILL.md +1 -1
- package/ai/skills/stacks-query-builder/SKILL.md +1 -1
- package/ai/skills/stacks-queue/SKILL.md +1 -1
- package/ai/skills/stacks-realtime/SKILL.md +1 -1
- package/ai/skills/stacks-registry/SKILL.md +1 -1
- package/ai/skills/stacks-repl/SKILL.md +1 -1
- package/ai/skills/stacks-retro/SKILL.md +121 -75
- package/ai/skills/stacks-review/SKILL.md +182 -74
- package/ai/skills/stacks-router/SKILL.md +1 -1
- package/ai/skills/stacks-routes/SKILL.md +1 -1
- package/ai/skills/stacks-scaffolding/SKILL.md +1 -1
- package/ai/skills/stacks-scheduler/SKILL.md +1 -1
- package/ai/skills/stacks-search-engine/SKILL.md +1 -1
- package/ai/skills/stacks-security/SKILL.md +1 -1
- package/ai/skills/stacks-security-audit/SKILL.md +1 -1
- package/ai/skills/stacks-server/SKILL.md +1 -1
- package/ai/skills/stacks-shell/SKILL.md +1 -1
- package/ai/skills/stacks-slug/SKILL.md +1 -1
- package/ai/skills/stacks-sms/SKILL.md +1 -1
- package/ai/skills/stacks-socials/SKILL.md +1 -1
- package/ai/skills/stacks-storage/SKILL.md +1 -1
- package/ai/skills/stacks-strings/SKILL.md +1 -1
- package/ai/skills/stacks-stx/SKILL.md +1 -1
- package/ai/skills/stacks-tdd/EXAMPLES.md +136 -0
- package/ai/skills/stacks-tdd/SKILL.md +125 -0
- package/ai/skills/stacks-testing/SKILL.md +13 -3
- package/ai/skills/stacks-tunnel/SKILL.md +1 -1
- package/ai/skills/stacks-types/SKILL.md +1 -1
- package/ai/skills/stacks-ui/SKILL.md +1 -1
- package/ai/skills/stacks-utils/SKILL.md +1 -1
- package/ai/skills/stacks-validation/SKILL.md +1 -1
- package/ai/skills/stacks-whois/SKILL.md +1 -1
- package/ai/skills/stacks-wizard/SKILL.md +127 -0
- package/ai/skills/stacks-wizard/scripts/template.sh +208 -0
- package/ai/skills/stacks-writing-for-agents/MECHANICS.md +125 -0
- package/ai/skills/stacks-writing-for-agents/SKILL.md +218 -0
- package/app/Actions/Auth/GenerateTwoFactorSecretAction.ts +12 -2
- package/app/Actions/Commerce/Shipping/{DriverDestroyAction.ts → CourierDestroyAction.ts} +6 -6
- package/app/Actions/Commerce/Shipping/{DriverIndexAction.ts → CourierIndexAction.ts} +3 -3
- package/app/Actions/Commerce/Shipping/CourierPingStoreAction.ts +61 -0
- package/app/Actions/Commerce/Shipping/{DriverShowAction.ts → CourierShowAction.ts} +5 -5
- package/app/Actions/Commerce/Shipping/{DriverStoreAction.ts → CourierStoreAction.ts} +4 -4
- package/app/Actions/Commerce/Shipping/{DriverUpdateAction.ts → CourierUpdateAction.ts} +6 -6
- package/app/Actions/Commerce/Shipping/DeliveryRouteStartAction.ts +38 -0
- package/app/Actions/Commerce/Shipping/DeliveryStopCompleteAction.ts +40 -0
- package/app/Actions/Commerce/Shipping/DeliveryStopFailAction.ts +44 -0
- package/app/Actions/Commerce/Shipping/DeliveryStopStartAction.ts +39 -0
- package/app/Actions/Commerce/Shipping/courier-session.ts +75 -0
- package/app/Actions/Commerce/commerce-action.test.ts +5 -5
- package/app/Actions/Dashboard/Commerce/CommerceDeliveryAction.ts +5 -5
- package/app/Actions/Dashboard/Commerce/CourierIndexAction.ts +24 -0
- package/app/Actions/Dashboard/Commerce/DeliveryRouteIndexAction.ts +7 -7
- package/app/Actions/Dashboard/Commerce/commerce-delivery.test.ts +11 -11
- package/app/Actions/Dashboard/Commerce/commerce-delivery.ts +29 -29
- package/app/Actions/Dashboard/Commerce/{driver-records.test.ts → courier-records.test.ts} +9 -9
- package/app/Actions/Dashboard/Commerce/{driver-records.ts → courier-records.ts} +14 -14
- package/app/Actions/Dashboard/Commerce/delivery-route-records.test.ts +13 -13
- package/app/Actions/Dashboard/Commerce/delivery-route-records.ts +25 -25
- package/app/Models/User.ts +1 -1
- package/app/Models/commerce/{Driver.ts → Courier.ts} +7 -7
- package/app/Models/commerce/{DriverPing.ts → CourierPing.ts} +7 -7
- package/app/Models/commerce/DeliveryRoute.ts +6 -6
- package/app/Models/commerce/DeliveryStop.ts +31 -8
- package/bootstrap.ts +7 -0
- package/functions/commerce/shippings/couriers.ts +19 -0
- package/ide/vscode/package.json +1 -1
- package/package.json +4 -3
- package/resources/components/Dashboard/Commerce/Delivery/{DriverDeleteDialog.stx → CourierDeleteDialog.stx} +5 -5
- package/resources/components/Dashboard/Commerce/Delivery/{DriverDialog.stx → CourierDialog.stx} +10 -10
- package/resources/components/Dashboard/Commerce/Delivery/{DriversDashboard.stx → CouriersDashboard.stx} +43 -43
- package/resources/components/Dashboard/Commerce/Delivery/{DriversTable.stx → CouriersTable.stx} +21 -21
- package/resources/components/Dashboard/Commerce/Delivery/DeliveryOverviewDashboard.stx +18 -18
- package/resources/components/Dashboard/Commerce/Delivery/DeliveryRouteDeleteDialog.stx +2 -2
- package/resources/components/Dashboard/Commerce/Delivery/DeliveryRouteDialog.stx +22 -22
- package/resources/components/Dashboard/Commerce/Delivery/DeliveryRoutesDashboard.stx +24 -24
- package/resources/components/Dashboard/Commerce/Delivery/DeliveryRoutesTable.stx +8 -8
- package/resources/components/Dashboard/Commerce/Delivery/TabNavigation.stx +1 -1
- package/resources/functions/dashboard/data.ts +1 -1
- package/resources/functions/dashboard/sidebar.ts +2 -2
- package/routes/dashboard-api.ts +6 -6
- package/routes/dashboard.ts +7 -7
- package/routes/delivery.ts +24 -0
- package/types/defaults.ts +3 -3
- package/views/dashboard/.discovered-models.json +18 -18
- package/views/dashboard/AUDIT.md +1 -1
- package/views/dashboard/commerce/delivery/{drivers.stx → couriers.stx} +2 -2
- package/views/dashboard/composables/useChart.ts +16 -2
- package/views/dashboard/layouts/default.stx +1 -1
- package/app/Actions/Dashboard/Commerce/DriverIndexAction.ts +0 -24
- package/functions/commerce/shippings/drivers.ts +0 -19
|
@@ -1,119 +1,247 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: stacks-investigate
|
|
3
|
-
description: Use when debugging
|
|
3
|
+
description: Use when debugging a Stacks issue - something broken, throwing, failing, flaky or slow. Builds a tight feedback loop that goes red on the bug before any hypothesis is allowed, then minimises, tests hypotheses, fixes and locks it down with a regression test. Enforces no fixes without root cause. Invoke with /stacks-investigate.
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: Bun >= 1.3.0, TypeScript
|
|
6
6
|
allowed-tools: Read Edit Write Bash Grep Glob
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
# /stacks-investigate
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
2. **
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
**
|
|
55
|
-
|
|
56
|
-
**
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
**
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
###
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
- [
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
9
|
+
# /stacks-investigate - root cause debugging
|
|
10
|
+
|
|
11
|
+
A discipline for hard bugs. Find the **root cause**, not a way to make the
|
|
12
|
+
symptom go away. Skip a phase only when you can say why.
|
|
13
|
+
|
|
14
|
+
Credit: the feedback-loop-first structure is adapted from Matt Pocock's
|
|
15
|
+
`diagnosing-bugs` skill (MIT), <https://github.com/mattpocock/skills>.
|
|
16
|
+
|
|
17
|
+
## Redact
|
|
18
|
+
|
|
19
|
+
This skill has you show commands, outputs and captured artifacts. **Redact every
|
|
20
|
+
secret first**, writing `<REDACTED>` in its place. Build loops against env vars
|
|
21
|
+
so the credential stays in the environment rather than in what you show. In a
|
|
22
|
+
Stacks project the usual offenders are `.env`, `.env.production`,
|
|
23
|
+
`config/services.ts`, `APP_KEY`, AWS keys and `HCLOUD_TOKEN`, plus captured HTTP
|
|
24
|
+
traffic carrying an `Authorization` header. Quote only the lines that carry the
|
|
25
|
+
signal.
|
|
26
|
+
|
|
27
|
+
If the redacted output is not enough to diagnose the bug, say so and ask the
|
|
28
|
+
user.
|
|
29
|
+
|
|
30
|
+
## Phase 1: build a feedback loop
|
|
31
|
+
|
|
32
|
+
**This is the skill.** Everything else is mechanical. With a **tight** pass/fail
|
|
33
|
+
signal, one that goes **red** on *this* bug, you will find the cause: bisection,
|
|
34
|
+
hypothesis testing and instrumentation all just consume it. Without one, no
|
|
35
|
+
amount of staring at code will save you.
|
|
36
|
+
|
|
37
|
+
Spend disproportionate effort here. Be aggressive, be creative, refuse to give
|
|
38
|
+
up.
|
|
39
|
+
|
|
40
|
+
### Ways to construct one, in roughly this order
|
|
41
|
+
|
|
42
|
+
1. **Failing test** at whatever seam reaches the bug. `bun test <path>` is the
|
|
43
|
+
loop. See `stacks-tdd` for which seam.
|
|
44
|
+
2. **HTTP script** against `buddy dev`, using `curl` or `Bun.fetch` with a
|
|
45
|
+
fixture payload.
|
|
46
|
+
3. **CLI invocation**, for instance `buddy <command>` with a fixture input,
|
|
47
|
+
diffing stdout against a known-good snapshot.
|
|
48
|
+
4. **REPL probe**. `buddy repl` reaches models, config and the query builder
|
|
49
|
+
directly, which is the fastest loop for an ORM or relationship bug.
|
|
50
|
+
5. **Headless browser script**. `/stacks-browse` drives a real browser over CDP
|
|
51
|
+
and asserts on DOM, console and network with nothing to install.
|
|
52
|
+
6. **Replay a captured trace.** Save a real request, payload or event log to
|
|
53
|
+
disk, then replay it through the code path in isolation.
|
|
54
|
+
7. **Throwaway harness.** A single file that boots the minimum (one action, a
|
|
55
|
+
seeded database) and exercises the bug path with one call.
|
|
56
|
+
8. **Deterministic database state.** `buddy migrate:fresh --seed` plus the
|
|
57
|
+
model factories gives byte-identical rows every run, which turns "sometimes
|
|
58
|
+
wrong" into "always wrong" more often than you would expect.
|
|
59
|
+
9. **Property or fuzz loop.** For "sometimes the output is wrong", run a
|
|
60
|
+
thousand inputs and look for the failure mode.
|
|
61
|
+
10. **Bisection harness.** If the bug appeared between two known states, automate
|
|
62
|
+
"boot at state X, check, repeat" so `git bisect run` can consume it.
|
|
63
|
+
11. **Differential loop.** Same input through two versions or two configs, diff
|
|
64
|
+
the outputs. This is the one for a dependency bump or a driver swap.
|
|
65
|
+
12. **HITL bash script.** Last resort. If a human must click, drive *them* with
|
|
66
|
+
[scripts/hitl-loop.template.sh](scripts/hitl-loop.template.sh) so the loop is
|
|
67
|
+
still structured, and the captured output feeds back to you.
|
|
68
|
+
|
|
69
|
+
Build the right feedback loop and the bug is 90% fixed.
|
|
70
|
+
|
|
71
|
+
### Tighten the loop
|
|
72
|
+
|
|
73
|
+
Treat the loop as a product. Once you have *a* loop, **tighten** it:
|
|
74
|
+
|
|
75
|
+
- Faster. Narrow the test path, skip unrelated init, reuse the seeded database
|
|
76
|
+
instead of re-migrating.
|
|
77
|
+
- Sharper signal. Assert on the specific symptom, not "it did not crash".
|
|
78
|
+
- More deterministic. Pin the clock, seed the RNG, isolate the filesystem, freeze
|
|
79
|
+
the network, and pick one driver rather than whatever `config/` happens to
|
|
80
|
+
select.
|
|
81
|
+
|
|
82
|
+
A 30-second flaky loop is barely better than no loop. A 2-second deterministic
|
|
83
|
+
one is a superpower.
|
|
84
|
+
|
|
85
|
+
### Non-deterministic bugs
|
|
86
|
+
|
|
87
|
+
The goal is not a clean repro but a **higher reproduction rate**. Loop the
|
|
88
|
+
trigger 100 times, parallelise, add stress, narrow the timing window, inject
|
|
89
|
+
sleeps. A 50% flake is debuggable, 1% is not, so keep raising the rate.
|
|
90
|
+
|
|
91
|
+
### When you genuinely cannot build a loop
|
|
92
|
+
|
|
93
|
+
Stop and say so explicitly. List what you tried. Ask the user for one of: access
|
|
94
|
+
to an environment that reproduces it, a redacted captured artifact (a HAR file, a
|
|
95
|
+
log dump from `storage/logs/stacks.log`, a screen recording with timestamps), or
|
|
96
|
+
permission to add temporary instrumentation in production. Do **not** proceed to
|
|
97
|
+
hypothesise without a loop.
|
|
98
|
+
|
|
99
|
+
### Completion criterion: a tight loop that goes red
|
|
100
|
+
|
|
101
|
+
Phase 1 is done when you can name **one command** that you have **already run at
|
|
102
|
+
least once**, showing the invocation and its output, redacted, and that is:
|
|
103
|
+
|
|
104
|
+
- [ ] **Red-capable.** It drives the actual bug code path and asserts the
|
|
105
|
+
**user's exact symptom**, so it can go red now and green once fixed. Not
|
|
106
|
+
"runs without erroring".
|
|
107
|
+
- [ ] **Deterministic.** Same verdict every run, or for a flaky bug, a pinned
|
|
108
|
+
high reproduction rate.
|
|
109
|
+
- [ ] **Fast.** Seconds, not minutes.
|
|
110
|
+
- [ ] **Agent-runnable.** You can run it unattended, with a human in the loop
|
|
111
|
+
only through the HITL template.
|
|
112
|
+
|
|
113
|
+
If you catch yourself reading code to build a theory before this command exists,
|
|
114
|
+
**stop. Jumping straight to a hypothesis is the exact failure this skill
|
|
115
|
+
prevents.** No red-capable command, no Phase 2.
|
|
116
|
+
|
|
117
|
+
## Phase 2: reproduce and minimise
|
|
118
|
+
|
|
119
|
+
Run the loop. Watch it go red.
|
|
120
|
+
|
|
121
|
+
Confirm:
|
|
122
|
+
|
|
123
|
+
- [ ] The loop produces the failure the **user** described, not a different one
|
|
124
|
+
that happens to be nearby. Wrong bug means wrong fix.
|
|
125
|
+
- [ ] It reproduces across multiple runs, or at a high enough rate to debug
|
|
126
|
+
against.
|
|
127
|
+
- [ ] You have captured the exact symptom (error message, wrong output, slow
|
|
128
|
+
timing) so later phases can verify the fix addresses it.
|
|
129
|
+
|
|
130
|
+
Then shrink the repro to the **smallest scenario that still goes red**. Cut
|
|
131
|
+
inputs, callers, config, middleware, seeded rows and steps **one at a time**,
|
|
132
|
+
re-running the loop after each cut, and keep only what is load-bearing.
|
|
133
|
+
|
|
134
|
+
A minimal repro shrinks the hypothesis space in Phase 3 and becomes the clean
|
|
135
|
+
regression test in Phase 5.
|
|
136
|
+
|
|
137
|
+
Done when **every remaining element is load-bearing**: removing any one of them
|
|
138
|
+
makes the loop go green.
|
|
139
|
+
|
|
140
|
+
## Phase 3: hypothesise
|
|
141
|
+
|
|
142
|
+
Generate **3 to 5 ranked hypotheses** before testing any of them.
|
|
143
|
+
Single-hypothesis generation anchors on the first plausible idea.
|
|
144
|
+
|
|
145
|
+
Each must be **falsifiable**, stating the prediction it makes:
|
|
146
|
+
|
|
147
|
+
> If X is the cause, then changing Y will make the bug disappear, or changing Z
|
|
148
|
+
> will make it worse.
|
|
149
|
+
|
|
150
|
+
If you cannot state the prediction, the hypothesis is a vibe. Discard or sharpen
|
|
151
|
+
it.
|
|
152
|
+
|
|
153
|
+
Gather the evidence that ranks them from where Stacks actually keeps it:
|
|
154
|
+
|
|
155
|
+
- `storage/logs/stacks.log` for the runtime trail.
|
|
156
|
+
- `git log --oneline -20 -- <paths>` for what changed recently.
|
|
157
|
+
- `config/*.ts` for which driver, connection or host is selected in this
|
|
158
|
+
environment.
|
|
159
|
+
- `app/Models/` and `storage/framework/defaults/app/Models/` for the model, and
|
|
160
|
+
`database/migrations/` for whether the schema matches it.
|
|
161
|
+
- `storage/framework/types/*.d.ts` and the auto-import manifests, which are
|
|
162
|
+
generated and go stale. A symbol that types as `any` in an app is usually this.
|
|
163
|
+
- `routes/`, `app/Middleware.ts` and `app/Events.ts` for the registries, where a
|
|
164
|
+
missing entry fails silently rather than loudly.
|
|
165
|
+
- `bun.lock` and `pantry.lock`. There are two install trees, and Bun resolves
|
|
166
|
+
`node_modules`, so verify the version that actually loads.
|
|
167
|
+
|
|
168
|
+
Show the ranked list to the user before testing. They often re-rank it instantly
|
|
169
|
+
("we just deployed a change to number three") or name one already ruled out. Do
|
|
170
|
+
not block on it. Proceed with your ranking if the user is away.
|
|
171
|
+
|
|
172
|
+
## Phase 4: instrument
|
|
173
|
+
|
|
174
|
+
Each probe maps to a specific prediction from Phase 3. **Change one variable at a
|
|
175
|
+
time.**
|
|
176
|
+
|
|
177
|
+
Tool preference:
|
|
178
|
+
|
|
179
|
+
1. **REPL or debugger inspection** where the environment supports it. One
|
|
180
|
+
breakpoint beats ten logs, and `buddy repl` is usually reachable.
|
|
181
|
+
2. **Targeted logs** at the boundaries that distinguish the hypotheses, via
|
|
182
|
+
`log.debug()` from `@stacksjs/logging`.
|
|
183
|
+
3. Never "log everything and grep".
|
|
184
|
+
|
|
185
|
+
**Tag every debug log** with a unique prefix such as `[DEBUG-a4f2]`, so cleanup
|
|
186
|
+
is a single grep. Untagged logs survive. Tagged ones die.
|
|
187
|
+
|
|
188
|
+
**Performance branch.** For a regression, logs are usually the wrong instrument.
|
|
189
|
+
Establish a baseline measurement first (a timing harness, `performance.now()`, a
|
|
190
|
+
profiler, the query plan), then bisect. Measure first, fix second. In a Stacks
|
|
191
|
+
app the first thing to measure is query count, because an N+1 through a
|
|
192
|
+
relationship looks exactly like "the framework got slower".
|
|
193
|
+
|
|
194
|
+
## Phase 5: fix and regression test
|
|
195
|
+
|
|
196
|
+
Write the regression test **before the fix**, but only if there is a **correct
|
|
197
|
+
seam** for it.
|
|
198
|
+
|
|
199
|
+
A correct seam is one where the test exercises the **real bug pattern** as it
|
|
200
|
+
occurs at the call site. If the only available seam is too shallow (a single
|
|
201
|
+
caller test when the bug needs several, a unit test that cannot replicate the
|
|
202
|
+
chain that triggered it), a test there gives false confidence.
|
|
203
|
+
|
|
204
|
+
**If no correct seam exists, that itself is the finding.** Note it. The
|
|
205
|
+
architecture is preventing the bug from being locked down, which is a
|
|
206
|
+
`stacks-codebase-design` problem, not a testing one.
|
|
207
|
+
|
|
208
|
+
If a correct seam exists:
|
|
209
|
+
|
|
210
|
+
1. Turn the minimised repro into a failing test at that seam.
|
|
211
|
+
2. Watch it fail.
|
|
212
|
+
3. Apply the fix. Change as little as possible.
|
|
213
|
+
4. Watch it pass.
|
|
214
|
+
5. Re-run the Phase 1 loop against the original, un-minimised scenario.
|
|
215
|
+
|
|
216
|
+
## Phase 6: cleanup
|
|
217
|
+
|
|
218
|
+
Required before declaring done:
|
|
219
|
+
|
|
220
|
+
- [ ] The original repro no longer reproduces. Re-run the Phase 1 loop.
|
|
221
|
+
- [ ] The regression test passes, or the absence of a seam is documented.
|
|
222
|
+
- [ ] All `[DEBUG-...]` instrumentation removed. Grep the prefix.
|
|
223
|
+
- [ ] Throwaway harnesses deleted, or moved to a clearly marked debug location.
|
|
224
|
+
- [ ] `./buddy lint:fix` and `./buddy typecheck` are clean.
|
|
225
|
+
- [ ] The hypothesis that turned out correct is stated in the commit message, so
|
|
226
|
+
the next debugger learns.
|
|
108
227
|
|
|
109
228
|
## Rules
|
|
110
229
|
|
|
111
|
-
- **No fixes without root cause.** If you
|
|
112
|
-
|
|
113
|
-
- **
|
|
114
|
-
|
|
115
|
-
- **
|
|
230
|
+
- **No fixes without root cause.** If you cannot explain why, you have not found
|
|
231
|
+
the bug.
|
|
232
|
+
- **Never apply a fix to see if it helps.** That is a hypothesis test with no
|
|
233
|
+
prediction and no cleanup.
|
|
234
|
+
- **Do not blame the framework first.** Application code and configuration are
|
|
235
|
+
wrong far more often than `storage/framework/core/` is.
|
|
236
|
+
- **Intermittent bugs are timing bugs** until proven otherwise. Look for a
|
|
237
|
+
missing `await`, a race, or shared mutable state.
|
|
238
|
+
- **If the fix runs past about 20 lines, question the root cause.** Large fixes
|
|
239
|
+
usually mean you are working around the problem.
|
|
240
|
+
- **Check the blast radius before you fix.** A change in `storage/framework/core/`
|
|
241
|
+
can reach 15+ downstream packages, and in a published package a change to a
|
|
242
|
+
`.d.ts` path can silently degrade consumers to `any`.
|
|
116
243
|
|
|
117
244
|
## Downstream
|
|
118
245
|
|
|
119
|
-
> **Fix applied.** Run `/stacks-review` to
|
|
246
|
+
> **Fix applied.** Run `/stacks-review` to review it, and `/stacks-retro` when
|
|
247
|
+
> the real lesson is that the environment let the bug hide.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Human-in-the-loop reproduction loop.
|
|
3
|
+
#
|
|
4
|
+
# Adapted from Matt Pocock's `diagnosing-bugs` skill (MIT),
|
|
5
|
+
# https://github.com/mattpocock/skills
|
|
6
|
+
# Copy this file, edit the steps below, and run it.
|
|
7
|
+
# The agent runs the script; the user follows prompts in their terminal.
|
|
8
|
+
#
|
|
9
|
+
# Usage:
|
|
10
|
+
# bash hitl-loop.template.sh
|
|
11
|
+
#
|
|
12
|
+
# Two helpers:
|
|
13
|
+
# step "<instruction>" → show instruction, wait for Enter
|
|
14
|
+
# capture VAR "<question>" → show question, read response into VAR
|
|
15
|
+
#
|
|
16
|
+
# At the end, captured values are printed as KEY=VALUE for the agent to parse.
|
|
17
|
+
#
|
|
18
|
+
# `capture` prints its value back to the terminal, where the agent reads it,
|
|
19
|
+
# so capture observations, and leave signing in to the user as a `step`.
|
|
20
|
+
|
|
21
|
+
set -euo pipefail
|
|
22
|
+
|
|
23
|
+
step() {
|
|
24
|
+
printf '\n>>> %s\n' "$1"
|
|
25
|
+
read -r -p " [Enter when done] " _
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
capture() {
|
|
29
|
+
local var="$1" question="$2" answer
|
|
30
|
+
printf '\n>>> %s\n' "$question"
|
|
31
|
+
read -r -p " > " answer
|
|
32
|
+
printf -v "$var" '%s' "$answer"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# --- edit below ---------------------------------------------------------
|
|
36
|
+
|
|
37
|
+
step "Run ./buddy dev, open the app, and sign in."
|
|
38
|
+
|
|
39
|
+
capture ERRORED "Click the 'Export' button. Did it throw an error? (y/n)"
|
|
40
|
+
|
|
41
|
+
capture ERROR_MSG "Paste the error message (or 'none'):"
|
|
42
|
+
|
|
43
|
+
# --- edit above ---------------------------------------------------------
|
|
44
|
+
|
|
45
|
+
printf '\n--- Captured ---\n'
|
|
46
|
+
printf 'ERRORED=%s\n' "$ERRORED"
|
|
47
|
+
printf 'ERROR_MSG=%s\n' "$ERROR_MSG"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: stacks-jobs
|
|
3
|
-
description: Use when creating background job classes in app/Jobs/
|
|
3
|
+
description: Use when creating background job classes in app/Jobs/ - job structure, the handle method, job configuration (queue, tries, backoff, timeout, rate), dispatching patterns (dispatch, dispatchIf, dispatchAfter, dispatchNow), or the Every schedule constants. For the queue system internals (workers, batching, events, drivers, testing), see stacks-queue.
|
|
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-listeners
|
|
3
|
-
description: Use when creating event listeners in app/Listeners/
|
|
3
|
+
description: Use when creating event listeners in app/Listeners/ - the listener file structure, registering listeners in app/Events.ts, the listener-to-action mapping pattern, CLI event listeners in Console.ts, or debugging listener execution. For the event system API (dispatch, listen, emitter, model events), see stacks-events.
|
|
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-logging
|
|
3
|
-
description: Use when implementing logging in Stacks
|
|
3
|
+
description: Use when implementing logging in Stacks - the log facade (info, error, warn, debug, success), dump/dd debugging, timing functions, file-based logging, or log configuration. Covers @stacksjs/logging and config/logging.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-mail
|
|
3
|
-
description: Use when creating mail classes in app/Mail/
|
|
3
|
+
description: Use when creating mail classes in app/Mail/ - defining email content and templates, using the template() function with STX or HTML templates, variable interpolation, email layouts, or the app-level mail sending pattern. For the email framework itself (drivers, Mail singleton, EmailSDK, inbox management), see stacks-email.
|
|
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-middleware
|
|
3
|
-
description: Use when working with middleware in a Stacks application
|
|
3
|
+
description: Use when working with middleware in a Stacks application - defining middleware, applying to routes, middleware aliases, parameterized middleware, groups, or the middleware execution pipeline. Covers the Middleware class, app/Middleware.ts alias registry, and all 22 default middleware files.
|
|
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-migrations
|
|
3
|
-
description: Use when working with database migrations in a Stacks application
|
|
3
|
+
description: Use when working with database migrations in a Stacks application - creating migration files, running migrations, fresh migration (drop + recreate), seeding after migration, migration file naming conventions, or the 96+ built-in migration files. For the database API itself (queries, connections, SQL helpers), see stacks-database.
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: Bun >= 1.3.0, TypeScript, SQLite >= 3.47.2
|
|
6
6
|
allowed-tools: Read Edit Write Bash Grep Glob
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: stacks-models
|
|
3
|
-
description: Use when working with data models in Stacks
|
|
3
|
+
description: Use when working with data models in Stacks - the defineModel() API, model attributes with validation and factories, relationships (hasOne/hasMany/belongsTo/belongsToMany), traits (useAuth, useUuid, useTimestamps, useSearch, useApi, billable, taggable, categorizable, commentable, likeable, observe), computed properties (get/set), model generation, and the 50+ built-in framework models. Covers model definitions and storage/framework/defaults/app/Models/.
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: Bun >= 1.3.0, TypeScript, SQLite >= 3.47.2
|
|
6
6
|
allowed-tools: Read Edit Write Bash Grep Glob
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: stacks-new-feature
|
|
3
|
-
description: Use when adding a new feature end-to-end in a Stacks application
|
|
3
|
+
description: Use when adding a new feature end-to-end in a Stacks application - slicing the work into tracer bullets, then building each slice from model through migration, action, route, test and deploy. Covers the recommended order of operations, the blocking edges between slices, and the expand-contract sequence for a wide refactor.
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: Bun >= 1.3.0, TypeScript
|
|
6
6
|
allowed-tools: Read Edit Write Bash Grep Glob
|
|
@@ -10,12 +10,66 @@ allowed-tools: Read Edit Write Bash Grep Glob
|
|
|
10
10
|
|
|
11
11
|
Step-by-step guide for building features end-to-end.
|
|
12
12
|
|
|
13
|
+
## Slice it first
|
|
14
|
+
|
|
15
|
+
Before any code, break the work into **tracer bullets**: vertical slices, each
|
|
16
|
+
cutting a narrow but complete path through every layer.
|
|
17
|
+
|
|
18
|
+
- Each slice cuts through model, migration, action, route and test. Vertical, not
|
|
19
|
+
a horizontal slice of one layer.
|
|
20
|
+
- A finished slice is demoable or verifiable on its own.
|
|
21
|
+
- Each slice fits in one fresh context window.
|
|
22
|
+
- Any prefactoring goes first. Make the change easy, then make the easy change.
|
|
23
|
+
|
|
24
|
+
Give each slice its **blocking edges**: the slices that must land before it can
|
|
25
|
+
start. A slice with no blockers can start immediately, and the set of slices
|
|
26
|
+
whose blockers are all done is the **frontier** you work from.
|
|
27
|
+
|
|
28
|
+
Present the breakdown as a numbered list before building anything. For each
|
|
29
|
+
slice: the title, what it delivers end to end, and what blocks it. Then ask
|
|
30
|
+
whether the granularity is right, whether the edges are real, and whether
|
|
31
|
+
anything should be merged or split. Iterate until the user approves.
|
|
32
|
+
|
|
33
|
+
Where the project tracks work on a real tracker, publish the slices in
|
|
34
|
+
dependency order so the edges can reference real identifiers. Where it does not,
|
|
35
|
+
one file per slice under `.scratch/<feature>/issues/<NN>-<slug>.md`, numbered
|
|
36
|
+
blockers-first, is enough. Avoid file paths and code snippets in either form,
|
|
37
|
+
because they go stale faster than the ticket does.
|
|
38
|
+
|
|
39
|
+
### The exception: a wide refactor
|
|
40
|
+
|
|
41
|
+
A **wide refactor** is one mechanical change whose blast radius fans across the
|
|
42
|
+
codebase, so a single edit breaks hundreds of call sites at once and no vertical
|
|
43
|
+
slice can land green. Renaming a model column, retyping a shared symbol, and
|
|
44
|
+
changing an exported signature in `storage/framework/core/` are all this shape.
|
|
45
|
+
|
|
46
|
+
Do not force it into a tracer bullet. Sequence it as **expand and contract**:
|
|
47
|
+
|
|
48
|
+
1. **Expand.** Add the new form beside the old so nothing breaks. A new column
|
|
49
|
+
alongside the old one, a new export alongside the old one.
|
|
50
|
+
2. **Migrate** the call sites in batches sized by blast radius, one per package or
|
|
51
|
+
directory, each batch its own slice blocked by the expand. CI stays green
|
|
52
|
+
batch to batch because the old form still exists.
|
|
53
|
+
3. **Contract.** Delete the old form once no caller remains, in a slice blocked by
|
|
54
|
+
every migrate batch.
|
|
55
|
+
|
|
56
|
+
When even the batches cannot stay green alone, keep the sequence but let them
|
|
57
|
+
share an integration branch that all block a final integrate-and-verify slice.
|
|
58
|
+
Green is promised only there.
|
|
59
|
+
|
|
60
|
+
Credit: the tracer-bullet and expand-contract framing is adapted from Matt
|
|
61
|
+
Pocock's `to-tickets` skill (MIT), <https://github.com/mattpocock/skills>.
|
|
62
|
+
|
|
13
63
|
## Workflow Overview
|
|
14
64
|
|
|
15
65
|
```
|
|
16
66
|
1. Model → 2. Migration → 3. Action → 4. Route → 5. Test → 6. Lint → 7. Deploy
|
|
17
67
|
```
|
|
18
68
|
|
|
69
|
+
Run this once per slice, not once per feature. Within a slice, `stacks-tdd`
|
|
70
|
+
owns the red-green loop: the migration lands, then the failing test, then the
|
|
71
|
+
code that passes it.
|
|
72
|
+
|
|
19
73
|
## Step 1: Define the Model
|
|
20
74
|
|
|
21
75
|
```typescript
|
|
@@ -119,7 +173,7 @@ route.group({ prefix: '/articles', middleware: ['auth'] }, () => {
|
|
|
119
173
|
})
|
|
120
174
|
```
|
|
121
175
|
|
|
122
|
-
Or rely on auto-generated routes from `useApi` trait
|
|
176
|
+
Or rely on auto-generated routes from `useApi` trait - they're created automatically.
|
|
123
177
|
|
|
124
178
|
### When a TypeScript client will call these
|
|
125
179
|
|
|
@@ -144,14 +198,14 @@ const client = createTypedClient<AppRoutes>({ baseUrl })
|
|
|
144
198
|
const created = await client.post('/articles', { title: 'x', content: 'y' })
|
|
145
199
|
```
|
|
146
200
|
|
|
147
|
-
Same runtime path, same middleware, same OpenAPI document
|
|
201
|
+
Same runtime path, same middleware, same OpenAPI document - the difference is
|
|
148
202
|
entirely at compile time. Keep the string form for routes no TypeScript consumer
|
|
149
203
|
calls; it stays lazily imported. See the `stacks-api` and `stacks-router` skills.
|
|
150
204
|
|
|
151
205
|
## Step 5: Add Event Listeners (Optional)
|
|
152
206
|
|
|
153
207
|
```typescript
|
|
154
|
-
// app/Events.ts
|
|
208
|
+
// app/Events.ts - add to existing
|
|
155
209
|
{
|
|
156
210
|
'article:created': ['NotifySubscribers'],
|
|
157
211
|
'article:published': ['SendNewsletter', 'IndexInSearchEngine']
|
|
@@ -225,9 +279,15 @@ export default new Job({
|
|
|
225
279
|
```
|
|
226
280
|
|
|
227
281
|
## Gotchas
|
|
228
|
-
- Models work directly via the dynamic ORM
|
|
282
|
+
- Models work directly via the dynamic ORM - no generation step needed before migrations
|
|
229
283
|
- The `useApi` trait auto-generates both routes AND dashboard views
|
|
230
284
|
- Model events (observe: true) emit `article:created`, `article:updated`, `article:deleted`
|
|
231
285
|
- Factories in model attributes are used by `buddy seed`
|
|
232
286
|
- Always lint after code generation: `bunx --bun pickier . --fix`
|
|
233
287
|
- Use conventional commits: `feat: add article management`
|
|
288
|
+
|
|
289
|
+
## Downstream
|
|
290
|
+
|
|
291
|
+
> **Slice green?** Run `/stacks-review` before merging it, then take the next
|
|
292
|
+
> slice off the frontier. `/stacks-tdd` is the loop inside each one, and
|
|
293
|
+
> `/stacks-plan-review` is where to go back to if the slices stop making sense.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: stacks-notifications
|
|
3
|
-
description: Use when implementing notifications in Stacks
|
|
3
|
+
description: Use when implementing notifications in Stacks - multi-channel notifications (email, SMS, push, chat, database), the database notification driver with read/unread tracking, notification factories (useEmail, useSMS, useChat, useDatabase), or notification configuration. Covers @stacksjs/notifications and config/notification.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-objects
|
|
3
|
-
description: Use when working with object manipulation in Stacks
|
|
3
|
+
description: Use when working with object manipulation in Stacks - deep merging with type safety, object mapping/transformation, strict key checking, typed entries/keys, property picking, clearing undefined values, or the DeepMerge utility type. Covers @stacksjs/objects.
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: Bun >= 1.3.0, TypeScript
|
|
6
6
|
allowed-tools: Read Edit Write Bash Grep Glob
|