acuvo-code 0.2.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/CHANGELOG.md +328 -0
- package/ENTERPRISE.md +927 -0
- package/LICENSE +120 -0
- package/README.md +1245 -0
- package/ROADMAP.md +556 -0
- package/bin/acuvo-mcp.mjs +208 -0
- package/bin/acuvo.mjs +3108 -0
- package/lib/acceptance-consent.mjs +168 -0
- package/lib/acceptance.mjs +859 -0
- package/lib/account.mjs +226 -0
- package/lib/acuvo-dir.mjs +72 -0
- package/lib/acuvo-models.mjs +141 -0
- package/lib/apply-patch.mjs +570 -0
- package/lib/ask-user.mjs +173 -0
- package/lib/audit.mjs +530 -0
- package/lib/auto-lease.mjs +174 -0
- package/lib/background.mjs +842 -0
- package/lib/best-of.mjs +334 -0
- package/lib/board.mjs +232 -0
- package/lib/breaker.mjs +93 -0
- package/lib/budget.mjs +1375 -0
- package/lib/builtin-skills.mjs +135 -0
- package/lib/cache-floor.mjs +204 -0
- package/lib/chain.mjs +303 -0
- package/lib/changed-paths.mjs +84 -0
- package/lib/chat.mjs +434 -0
- package/lib/checkpoint.mjs +637 -0
- package/lib/child-lifetime.mjs +71 -0
- package/lib/cli-args.mjs +1255 -0
- package/lib/code-review.mjs +1382 -0
- package/lib/colour.mjs +82 -0
- package/lib/command.mjs +2847 -0
- package/lib/compact.mjs +1151 -0
- package/lib/completion.mjs +515 -0
- package/lib/creative-engines.mjs +779 -0
- package/lib/db-inspect.mjs +1624 -0
- package/lib/delete.mjs +111 -0
- package/lib/design-loop.mjs +570 -0
- package/lib/diff-preview.mjs +1044 -0
- package/lib/doctor.mjs +2139 -0
- package/lib/dropped.mjs +216 -0
- package/lib/edit-diagnostics.mjs +277 -0
- package/lib/edit.mjs +460 -0
- package/lib/env-file.mjs +250 -0
- package/lib/escalate.mjs +702 -0
- package/lib/evaluate.mjs +284 -0
- package/lib/fetch-text.mjs +952 -0
- package/lib/fleet-budget.mjs +256 -0
- package/lib/gh.mjs +1536 -0
- package/lib/git.mjs +1341 -0
- package/lib/github.mjs +261 -0
- package/lib/h2.mjs +194 -0
- package/lib/handoff.mjs +417 -0
- package/lib/hooks.mjs +626 -0
- package/lib/http-probe.mjs +907 -0
- package/lib/image-director.mjs +322 -0
- package/lib/image-edit.mjs +522 -0
- package/lib/imagegen.mjs +998 -0
- package/lib/interrupt.mjs +234 -0
- package/lib/learned.mjs +353 -0
- package/lib/lease-watch.mjs +115 -0
- package/lib/lease.mjs +868 -0
- package/lib/localize.mjs +834 -0
- package/lib/log-tail.mjs +1052 -0
- package/lib/login.mjs +157 -0
- package/lib/lsp.mjs +1613 -0
- package/lib/mcp-consent.mjs +377 -0
- package/lib/mcp-defaults.mjs +780 -0
- package/lib/mcp-server.mjs +1343 -0
- package/lib/mcp.mjs +1263 -0
- package/lib/media.mjs +1283 -0
- package/lib/memory-workspace.mjs +179 -0
- package/lib/model-json.mjs +132 -0
- package/lib/model-tier.mjs +171 -0
- package/lib/model.mjs +1445 -0
- package/lib/parallel.mjs +144 -0
- package/lib/perchance.mjs +210 -0
- package/lib/plan-coherence.mjs +1461 -0
- package/lib/plan-ledger.mjs +981 -0
- package/lib/plan.mjs +461 -0
- package/lib/policy.mjs +783 -0
- package/lib/prefix-order.mjs +38 -0
- package/lib/project-memory.mjs +127 -0
- package/lib/prompt.mjs +109 -0
- package/lib/python.mjs +862 -0
- package/lib/rcfile.mjs +853 -0
- package/lib/read-window.mjs +743 -0
- package/lib/refute-tools.mjs +34 -0
- package/lib/refute.mjs +806 -0
- package/lib/repl-driver.mjs +264 -0
- package/lib/repl.mjs +324 -0
- package/lib/replay.mjs +1218 -0
- package/lib/repo-map.mjs +1101 -0
- package/lib/report.mjs +419 -0
- package/lib/search-rank.mjs +99 -0
- package/lib/search.mjs +659 -0
- package/lib/secret-paths.mjs +54 -0
- package/lib/session.mjs +1017 -0
- package/lib/skills.mjs +703 -0
- package/lib/slash.mjs +356 -0
- package/lib/spawn-argv.mjs +1151 -0
- package/lib/spend.mjs +250 -0
- package/lib/steer.mjs +280 -0
- package/lib/stream.mjs +253 -0
- package/lib/stuck.mjs +712 -0
- package/lib/subagent.mjs +749 -0
- package/lib/terminal-graphics.mjs +171 -0
- package/lib/tool-prefix.mjs +226 -0
- package/lib/tool-shortlist.mjs +162 -0
- package/lib/tools.mjs +2333 -0
- package/lib/tsserver.mjs +423 -0
- package/lib/turn.mjs +5672 -0
- package/lib/untrusted-block.mjs +271 -0
- package/lib/verify-claim.mjs +299 -0
- package/lib/vision.mjs +330 -0
- package/lib/voice-task.mjs +561 -0
- package/lib/warm-provider.mjs +255 -0
- package/lib/websearch.mjs +401 -0
- package/lib/workspace.mjs +928 -0
- package/lib/write-approval.mjs +235 -0
- package/lib/write-many.mjs +162 -0
- package/package.json +62 -0
- package/scripts/bundle.mjs +768 -0
- package/scripts/cache-floor.mjs +176 -0
- package/scripts/machine.mjs +226 -0
- package/scripts/test.mjs +139 -0
- package/skills/accessibility.md +87 -0
- package/skills/acuvo-design-system.md +123 -0
- package/skills/animation.md +84 -0
- package/skills/api-design.md +82 -0
- package/skills/auth-and-sessions.md +78 -0
- package/skills/build-with-a-framework.md +101 -0
- package/skills/colour-and-contrast.md +112 -0
- package/skills/creative-engines.md +81 -0
- package/skills/css-layout.md +85 -0
- package/skills/data-and-charts.md +77 -0
- package/skills/debugging.md +76 -0
- package/skills/designing-by-looking.md +84 -0
- package/skills/error-handling.md +78 -0
- package/skills/forms-and-validation.md +93 -0
- package/skills/nextjs-app-router.md +75 -0
- package/skills/page-composition.md +103 -0
- package/skills/performance.md +77 -0
- package/skills/plan-before-building.md +52 -0
- package/skills/planning-and-delegating.md +72 -0
- package/skills/refactoring.md +70 -0
- package/skills/security-basics.md +76 -0
- package/skills/state-management.md +73 -0
- package/skills/supabase-multitenant.md +72 -0
- package/skills/typescript-strict.md +90 -0
- package/skills/typography.md +135 -0
- package/skills/verify-your-own-work.md +62 -0
- package/skills/web-app-quality.md +62 -0
- package/skills/working-in-the-background.md +64 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: typography
|
|
3
|
+
description: Type scale, pairing, measure and rhythm — the largest single lever on whether a page reads as designed
|
|
4
|
+
when: Any page with words on it, which is every page. Read before choosing fonts or sizes.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Typography
|
|
8
|
+
|
|
9
|
+
Most generated pages fail here before they fail anywhere else. The colours are
|
|
10
|
+
fine, the layout is fine, and it still looks like a template — because every
|
|
11
|
+
heading is bold, every size is a round number, and the body text runs the full
|
|
12
|
+
width of a monitor.
|
|
13
|
+
|
|
14
|
+
## ⭐ The four decisions, in the order they matter
|
|
15
|
+
|
|
16
|
+
1. **Measure** — how wide a line of body text is.
|
|
17
|
+
2. **Scale** — the ratio between sizes.
|
|
18
|
+
3. **Weight contrast** — how far apart the heaviest and lightest are.
|
|
19
|
+
4. **Which fonts** — genuinely last. A well-set page in one system font beats a
|
|
20
|
+
badly-set page in two beautiful ones.
|
|
21
|
+
|
|
22
|
+
## 1. Measure: 60–75 characters, always
|
|
23
|
+
|
|
24
|
+
```css
|
|
25
|
+
.prose { max-width: 68ch; }
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`ch` is the width of a "0", so `68ch` is roughly 68 characters *at that font
|
|
29
|
+
size* — it stays correct when the size changes, which a `max-width: 720px` does
|
|
30
|
+
not.
|
|
31
|
+
|
|
32
|
+
⚠️ **This is the most common single defect in generated pages.** Body text
|
|
33
|
+
spanning 1400px is unreadable, and it is unreadable in a way people feel
|
|
34
|
+
without being able to name. Headings may run wider (they are short); body,
|
|
35
|
+
never.
|
|
36
|
+
|
|
37
|
+
## 2. A scale, not arbitrary sizes
|
|
38
|
+
|
|
39
|
+
Pick a ratio and multiply. Do not choose sizes by feel — that is what produces
|
|
40
|
+
`18px` next to `19px`, a difference nobody can see doing work nobody notices.
|
|
41
|
+
|
|
42
|
+
| use | ratio 1.25 (calm, editorial) | ratio 1.333 (louder, marketing) |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| small print | 0.8rem | 0.75rem |
|
|
45
|
+
| body | 1rem | 1rem |
|
|
46
|
+
| lead / large body | 1.25rem | 1.333rem |
|
|
47
|
+
| h3 | 1.563rem | 1.777rem |
|
|
48
|
+
| h2 | 1.953rem | 2.369rem |
|
|
49
|
+
| h1 | 2.441rem | 3.157rem |
|
|
50
|
+
|
|
51
|
+
The vendored system already ships a scale — **use those tokens rather than
|
|
52
|
+
re-deriving one.** Two scales in one page is worse than either alone.
|
|
53
|
+
|
|
54
|
+
⭐ **Hero headings break the scale on purpose.** A landing page hero often wants
|
|
55
|
+
`clamp(2.5rem, 6vw, 5rem)` — bigger than the scale's top step. That is a
|
|
56
|
+
deliberate exception at one place, not permission to freestyle everywhere.
|
|
57
|
+
|
|
58
|
+
## 3. Weight and contrast
|
|
59
|
+
|
|
60
|
+
- Body **400**. Headings **600–700**. That is the whole system for most pages.
|
|
61
|
+
- ⚠️ **Do not bold everything.** When four things are bold, nothing is
|
|
62
|
+
emphasised. Emphasis is a ratio, not a property.
|
|
63
|
+
- **Contrast size before you contrast weight.** A 2.4rem/600 heading over
|
|
64
|
+
1rem/400 body has far more presence than 1.2rem/800 over 1rem/700.
|
|
65
|
+
- Below 500, avoid pairing a light weight with small sizes — it fails contrast
|
|
66
|
+
checks and looks broken on Windows.
|
|
67
|
+
|
|
68
|
+
## 4. Choosing fonts
|
|
69
|
+
|
|
70
|
+
Google Fonts is the **only** external font host that loads under our CSP
|
|
71
|
+
(see `acuvo-design-system`). Anything else fails silently and the page falls
|
|
72
|
+
back to Times New Roman, which is the single most recognisable "the AI failed"
|
|
73
|
+
signal there is.
|
|
74
|
+
|
|
75
|
+
```html
|
|
76
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
77
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
78
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
⚠️ **Load only the weights used.** Every extra weight is a real download. Three
|
|
82
|
+
is usually right; five is almost never.
|
|
83
|
+
|
|
84
|
+
**Pairings that reliably work:**
|
|
85
|
+
|
|
86
|
+
| feel | display / headings | body |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| modern product, SaaS | Inter 600–700 | Inter 400 |
|
|
89
|
+
| editorial, premium | Fraunces / Playfair Display | Inter / Source Sans 3 |
|
|
90
|
+
| technical, developer | Space Grotesk | IBM Plex Sans |
|
|
91
|
+
| warm, human, local trade | Bricolage Grotesque | Karla |
|
|
92
|
+
| luxury, restrained | Cormorant Garamond | Jost |
|
|
93
|
+
|
|
94
|
+
⭐ **One family, two weights, is a legitimate and often superior answer.** Inter
|
|
95
|
+
600 over Inter 400 with a real size scale looks intentional. Two display faces
|
|
96
|
+
fighting each other looks like a template.
|
|
97
|
+
|
|
98
|
+
⚠️ Never pair two serifs, or two geometric sans. If they are similar enough to
|
|
99
|
+
be confused, the pairing reads as a mistake rather than a choice.
|
|
100
|
+
|
|
101
|
+
## 5. Rhythm — the part that gets skipped
|
|
102
|
+
|
|
103
|
+
- **Line height scales inversely with size.** Body `1.5–1.7`. Headings
|
|
104
|
+
`1.05–1.25`. A 3rem heading at `line-height: 1.5` has a canyon through it.
|
|
105
|
+
- **Letter-spacing likewise.** Large display type wants slightly negative
|
|
106
|
+
(`-0.02em` to `-0.03em`); small caps and overlines want positive
|
|
107
|
+
(`0.08em`–`0.12em`). Body wants none.
|
|
108
|
+
- **Space belongs above a heading, not below it.** A heading should sit close to
|
|
109
|
+
the text it introduces and far from the text it follows — that is what makes
|
|
110
|
+
a page scannable. `margin-block: 2.5em 0.6em`.
|
|
111
|
+
|
|
112
|
+
```css
|
|
113
|
+
h2 { font-size: 1.953rem; line-height: 1.15; letter-spacing: -0.02em; margin-block: 2.5em 0.6em; }
|
|
114
|
+
p { font-size: 1rem; line-height: 1.65; max-width: 68ch; }
|
|
115
|
+
.overline { font-size: 0.75rem; letter-spacing: 0.12em; text-transform: uppercase; }
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## 6. Details that separate careful from careless
|
|
119
|
+
|
|
120
|
+
- Use real punctuation: `"` `"` `'` `—` `…`, not `"` and `--`.
|
|
121
|
+
- `text-wrap: balance` on headings, `text-wrap: pretty` on paragraphs. Two
|
|
122
|
+
lines, no orphans, free.
|
|
123
|
+
- Numbers in tables: `font-variant-numeric: tabular-nums`, or columns jitter.
|
|
124
|
+
- ⚠️ Never centre a paragraph longer than two lines. Centred ragged-left text
|
|
125
|
+
is hard to read because the eye loses the line start.
|
|
126
|
+
- `font-size` on `<html>` stays at the browser default. Setting `62.5%` or a px
|
|
127
|
+
value overrides someone's accessibility setting.
|
|
128
|
+
|
|
129
|
+
## Before calling it done
|
|
130
|
+
|
|
131
|
+
- Body text is capped near `68ch`. Nothing runs the full viewport.
|
|
132
|
+
- Every size comes from the scale (one deliberate hero exception allowed).
|
|
133
|
+
- At most three weights are loaded, and all of them are used.
|
|
134
|
+
- Headings have tighter line-height than body, and more space above than below.
|
|
135
|
+
- The page still reads correctly at 320px and at 200% browser zoom.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: verify-your-own-work
|
|
3
|
+
description: How to prove a change works — mutation testing, and why "it builds" proves nothing
|
|
4
|
+
when: After writing code, adding a test, or before reporting something as done
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Proving it works
|
|
8
|
+
|
|
9
|
+
## "It builds" is not evidence
|
|
10
|
+
|
|
11
|
+
A clean build proves the code parses. It does not prove the feature is reachable,
|
|
12
|
+
that the test would catch a regression, or that a human can get to it.
|
|
13
|
+
|
|
14
|
+
The three claims, from weakest to strongest:
|
|
15
|
+
1. *It compiles.* — almost worthless.
|
|
16
|
+
2. *The tests pass.* — worth something, IF the tests can fail.
|
|
17
|
+
3. *I ran the real path end to end and observed the result.* — this is evidence.
|
|
18
|
+
|
|
19
|
+
## ⚠️⚠️ Mutation-test every guard you write
|
|
20
|
+
|
|
21
|
+
A test that cannot fail is worse than no test: it costs the same to maintain and
|
|
22
|
+
it actively certifies broken code.
|
|
23
|
+
|
|
24
|
+
**After writing a check, break the thing it guards and confirm the test goes
|
|
25
|
+
RED. Then restore and confirm GREEN.**
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
1. write the guard → green
|
|
29
|
+
2. break the code it guards → MUST go red ← if it stays green, the test is fake
|
|
30
|
+
3. restore → green again
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Real examples of tests that passed while guarding nothing:
|
|
34
|
+
- a regex missing anchors, so `abc<valid>def` passed
|
|
35
|
+
- `toContain('<Widget')`, satisfied by `<WidgetX` — the component was renamed and
|
|
36
|
+
the test never noticed
|
|
37
|
+
- a check whose verdict depended on the OS path separator: it passed on CI and
|
|
38
|
+
failed only on the developer's machine
|
|
39
|
+
|
|
40
|
+
## Only the end-to-end run proves reach
|
|
41
|
+
|
|
42
|
+
The most expensive recurring defect is **built but unreachable**: the function
|
|
43
|
+
exists, the tests pass, and nothing can actually invoke it. A registered tool
|
|
44
|
+
that never fires, a page with no link to it, an export with no importer.
|
|
45
|
+
|
|
46
|
+
So before "done": run the real path. Open the page. Call the endpoint. Check the
|
|
47
|
+
row landed in the database.
|
|
48
|
+
|
|
49
|
+
## Say what you did not check
|
|
50
|
+
|
|
51
|
+
If you tested three of five cases, say which two you did not. An honest partial
|
|
52
|
+
result is useful; an implied "all good" that turns out to be a third is not.
|
|
53
|
+
|
|
54
|
+
## When a check fails, doubt the check first
|
|
55
|
+
|
|
56
|
+
A failing test means one of two things and they are not equally likely:
|
|
57
|
+
1. the code is broken
|
|
58
|
+
2. **the check is wrong**
|
|
59
|
+
|
|
60
|
+
Read the failure literally and verify each link in its chain before "fixing" the
|
|
61
|
+
code. Changing correct code to satisfy a broken test is a real and common way to
|
|
62
|
+
make software worse while feeling productive.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: web-app-quality
|
|
3
|
+
description: What makes a generated app actually work — state, persistence, accessibility, edge cases
|
|
4
|
+
when: Building an interactive app, tool or anything with user input
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Making the app actually work
|
|
8
|
+
|
|
9
|
+
## Persist by default
|
|
10
|
+
|
|
11
|
+
An app that forgets everything on refresh feels broken even when it is
|
|
12
|
+
functionally correct. Persist user state to `localStorage` under one namespaced
|
|
13
|
+
key, and read it back on load.
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
const KEY = 'myapp:v1';
|
|
17
|
+
const load = () => { try { return JSON.parse(localStorage.getItem(KEY)) ?? null; } catch { return null; } };
|
|
18
|
+
const save = (s) => { try { localStorage.setItem(KEY, JSON.stringify(s)); } catch {} };
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
⚠️ Always `try/catch`. `localStorage` throws in private mode and when full, and
|
|
22
|
+
an uncaught throw during load blanks the whole app.
|
|
23
|
+
|
|
24
|
+
⚠️ Version the key (`:v1`). Shipping a new shape against an old stored object is
|
|
25
|
+
how an app crashes only for returning users — the ones who liked it.
|
|
26
|
+
|
|
27
|
+
## Input, and the cases that break it
|
|
28
|
+
|
|
29
|
+
Handle every one of these before saying done:
|
|
30
|
+
|
|
31
|
+
- **Empty submit** — do nothing, or say what is required. Never add a blank row.
|
|
32
|
+
- **Whitespace only** — `.trim()` before validating.
|
|
33
|
+
- **Duplicate** — decide: reject, merge, or allow. Do not crash.
|
|
34
|
+
- **Very long input** — clamp or wrap. One 500-character word must not break layout.
|
|
35
|
+
- **Numbers** — reject `NaN`. `Number('')` is `0`, which silently accepts empty.
|
|
36
|
+
- **Zero and negative** — a quantity of 0 is different from no quantity.
|
|
37
|
+
|
|
38
|
+
## Keyboard and accessibility
|
|
39
|
+
|
|
40
|
+
- Every interactive thing is a `<button>` or `<a>`, never a `<div onclick>`.
|
|
41
|
+
- `Enter` submits the form the user is in; `Escape` closes what just opened.
|
|
42
|
+
- Visible focus rings. Do not `outline: none` without a replacement.
|
|
43
|
+
- Labels tied to inputs (`<label for>`), and `aria-label` on icon-only buttons.
|
|
44
|
+
- Colour is never the only signal — pair it with text or an icon.
|
|
45
|
+
|
|
46
|
+
## Destructive actions
|
|
47
|
+
|
|
48
|
+
Deleting needs either a confirm or an undo. Undo is better: it keeps the app
|
|
49
|
+
fast and forgiving. A confirm dialog on every delete trains people to click
|
|
50
|
+
through it.
|
|
51
|
+
|
|
52
|
+
## Numbers and dates
|
|
53
|
+
|
|
54
|
+
- Format money with `Intl.NumberFormat`, never `toFixed(2)` plus a `$`.
|
|
55
|
+
- Dates with `Intl.DateTimeFormat` — never build a date string by hand.
|
|
56
|
+
- Show relative time ("2 minutes ago") for recent things, absolute for old.
|
|
57
|
+
|
|
58
|
+
## Before calling it done
|
|
59
|
+
|
|
60
|
+
Run through it as a user: add something, refresh, edit it, delete it, undo,
|
|
61
|
+
submit an empty form, paste a wall of text, use only the keyboard. Every one of
|
|
62
|
+
those is a bug people actually hit.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: working-in-the-background
|
|
3
|
+
description: Servers, watchers and long builds without blocking — start_process and wait_for_output
|
|
4
|
+
when: Whenever a command does not exit on its own — a server, a watcher, a long build, anything you need running WHILE you work
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Working In The Background
|
|
8
|
+
|
|
9
|
+
## ⚠️⚠️ `run_command` is for commands that FINISH
|
|
10
|
+
|
|
11
|
+
A dev server never finishes. Starting one with `run_command` blocks until the
|
|
12
|
+
timeout and then reports a failure for something that was working perfectly.
|
|
13
|
+
|
|
14
|
+
**Use `start_process` for anything that keeps running:** a dev server, a
|
|
15
|
+
watcher, a build in watch mode, a queue worker.
|
|
16
|
+
|
|
17
|
+
## ⭐⭐ The sequence that works every time
|
|
18
|
+
|
|
19
|
+
1. **`start_process`** — launch it. You get an `id` back.
|
|
20
|
+
2. **`wait_for_output`** — block until the line that means READY appears
|
|
21
|
+
(`Ready in`, `Listening on`, `compiled successfully`).
|
|
22
|
+
3. **`check_process`** — read what it printed, confirm it is still alive, and —
|
|
23
|
+
if it announced a port — confirm it is **actually answering HTTP**.
|
|
24
|
+
4. Do your work.
|
|
25
|
+
5. **`stop_process`** — stops it and everything it started, returns final output.
|
|
26
|
+
|
|
27
|
+
⭐ **`wait_for_output` instead of guessing.** Sleeping "about thirty seconds"
|
|
28
|
+
is wrong in both directions: too short and you test a server that has not
|
|
29
|
+
started, too long and you waste half a minute on every run. Wait for the line.
|
|
30
|
+
|
|
31
|
+
## ⚠️⚠️ Waiting for ONLY the success line will hang on a crash
|
|
32
|
+
|
|
33
|
+
If the process dies during startup, the ready line never comes and you sit
|
|
34
|
+
there until the timeout learning nothing.
|
|
35
|
+
|
|
36
|
+
⭐ **Wait for a pattern that also matches failure** — `Ready in`, but also
|
|
37
|
+
`Error`, `EADDRINUSE`, `Cannot find module`. Then read the output and find out
|
|
38
|
+
which happened. **Silence is not success**, and a wait that can only end one way
|
|
39
|
+
turns a five-second crash into a two-minute mystery.
|
|
40
|
+
|
|
41
|
+
## ⭐ A port answering is the only proof it started
|
|
42
|
+
|
|
43
|
+
`check_process` tells you whether the port actually responds. Use that, not the
|
|
44
|
+
log line — a framework can print "Ready" and still fail the first request. If
|
|
45
|
+
you are about to test a page, confirm the port answers first, or you will spend
|
|
46
|
+
the next three steps debugging your test instead of the app.
|
|
47
|
+
|
|
48
|
+
## ⚠️ Long logs: `summarize_log`, not the whole thing
|
|
49
|
+
|
|
50
|
+
A watch-mode build produces thousands of lines. `summarize_log` folds it to the
|
|
51
|
+
errors and warnings first, then the tail, then **an exact count of what was left
|
|
52
|
+
out** — so you know whether you are seeing everything.
|
|
53
|
+
|
|
54
|
+
Reading a 4,000-line log in full costs a large part of your context and usually
|
|
55
|
+
tells you one thing you could have had from the summary.
|
|
56
|
+
|
|
57
|
+
## ⭐ Clean up
|
|
58
|
+
|
|
59
|
+
**Stop what you started.** A dev server left running holds its port, and the
|
|
60
|
+
next run fails with `EADDRINUSE` — which reads like a broken app and is not.
|
|
61
|
+
If a port is busy, check whether YOU left something on it before concluding
|
|
62
|
+
anything about the code.
|
|
63
|
+
|
|
64
|
+
Related skills: `debugging`, `verify-your-own-work`.
|