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.
Files changed (154) hide show
  1. package/CHANGELOG.md +328 -0
  2. package/ENTERPRISE.md +927 -0
  3. package/LICENSE +120 -0
  4. package/README.md +1245 -0
  5. package/ROADMAP.md +556 -0
  6. package/bin/acuvo-mcp.mjs +208 -0
  7. package/bin/acuvo.mjs +3108 -0
  8. package/lib/acceptance-consent.mjs +168 -0
  9. package/lib/acceptance.mjs +859 -0
  10. package/lib/account.mjs +226 -0
  11. package/lib/acuvo-dir.mjs +72 -0
  12. package/lib/acuvo-models.mjs +141 -0
  13. package/lib/apply-patch.mjs +570 -0
  14. package/lib/ask-user.mjs +173 -0
  15. package/lib/audit.mjs +530 -0
  16. package/lib/auto-lease.mjs +174 -0
  17. package/lib/background.mjs +842 -0
  18. package/lib/best-of.mjs +334 -0
  19. package/lib/board.mjs +232 -0
  20. package/lib/breaker.mjs +93 -0
  21. package/lib/budget.mjs +1375 -0
  22. package/lib/builtin-skills.mjs +135 -0
  23. package/lib/cache-floor.mjs +204 -0
  24. package/lib/chain.mjs +303 -0
  25. package/lib/changed-paths.mjs +84 -0
  26. package/lib/chat.mjs +434 -0
  27. package/lib/checkpoint.mjs +637 -0
  28. package/lib/child-lifetime.mjs +71 -0
  29. package/lib/cli-args.mjs +1255 -0
  30. package/lib/code-review.mjs +1382 -0
  31. package/lib/colour.mjs +82 -0
  32. package/lib/command.mjs +2847 -0
  33. package/lib/compact.mjs +1151 -0
  34. package/lib/completion.mjs +515 -0
  35. package/lib/creative-engines.mjs +779 -0
  36. package/lib/db-inspect.mjs +1624 -0
  37. package/lib/delete.mjs +111 -0
  38. package/lib/design-loop.mjs +570 -0
  39. package/lib/diff-preview.mjs +1044 -0
  40. package/lib/doctor.mjs +2139 -0
  41. package/lib/dropped.mjs +216 -0
  42. package/lib/edit-diagnostics.mjs +277 -0
  43. package/lib/edit.mjs +460 -0
  44. package/lib/env-file.mjs +250 -0
  45. package/lib/escalate.mjs +702 -0
  46. package/lib/evaluate.mjs +284 -0
  47. package/lib/fetch-text.mjs +952 -0
  48. package/lib/fleet-budget.mjs +256 -0
  49. package/lib/gh.mjs +1536 -0
  50. package/lib/git.mjs +1341 -0
  51. package/lib/github.mjs +261 -0
  52. package/lib/h2.mjs +194 -0
  53. package/lib/handoff.mjs +417 -0
  54. package/lib/hooks.mjs +626 -0
  55. package/lib/http-probe.mjs +907 -0
  56. package/lib/image-director.mjs +322 -0
  57. package/lib/image-edit.mjs +522 -0
  58. package/lib/imagegen.mjs +998 -0
  59. package/lib/interrupt.mjs +234 -0
  60. package/lib/learned.mjs +353 -0
  61. package/lib/lease-watch.mjs +115 -0
  62. package/lib/lease.mjs +868 -0
  63. package/lib/localize.mjs +834 -0
  64. package/lib/log-tail.mjs +1052 -0
  65. package/lib/login.mjs +157 -0
  66. package/lib/lsp.mjs +1613 -0
  67. package/lib/mcp-consent.mjs +377 -0
  68. package/lib/mcp-defaults.mjs +780 -0
  69. package/lib/mcp-server.mjs +1343 -0
  70. package/lib/mcp.mjs +1263 -0
  71. package/lib/media.mjs +1283 -0
  72. package/lib/memory-workspace.mjs +179 -0
  73. package/lib/model-json.mjs +132 -0
  74. package/lib/model-tier.mjs +171 -0
  75. package/lib/model.mjs +1445 -0
  76. package/lib/parallel.mjs +144 -0
  77. package/lib/perchance.mjs +210 -0
  78. package/lib/plan-coherence.mjs +1461 -0
  79. package/lib/plan-ledger.mjs +981 -0
  80. package/lib/plan.mjs +461 -0
  81. package/lib/policy.mjs +783 -0
  82. package/lib/prefix-order.mjs +38 -0
  83. package/lib/project-memory.mjs +127 -0
  84. package/lib/prompt.mjs +109 -0
  85. package/lib/python.mjs +862 -0
  86. package/lib/rcfile.mjs +853 -0
  87. package/lib/read-window.mjs +743 -0
  88. package/lib/refute-tools.mjs +34 -0
  89. package/lib/refute.mjs +806 -0
  90. package/lib/repl-driver.mjs +264 -0
  91. package/lib/repl.mjs +324 -0
  92. package/lib/replay.mjs +1218 -0
  93. package/lib/repo-map.mjs +1101 -0
  94. package/lib/report.mjs +419 -0
  95. package/lib/search-rank.mjs +99 -0
  96. package/lib/search.mjs +659 -0
  97. package/lib/secret-paths.mjs +54 -0
  98. package/lib/session.mjs +1017 -0
  99. package/lib/skills.mjs +703 -0
  100. package/lib/slash.mjs +356 -0
  101. package/lib/spawn-argv.mjs +1151 -0
  102. package/lib/spend.mjs +250 -0
  103. package/lib/steer.mjs +280 -0
  104. package/lib/stream.mjs +253 -0
  105. package/lib/stuck.mjs +712 -0
  106. package/lib/subagent.mjs +749 -0
  107. package/lib/terminal-graphics.mjs +171 -0
  108. package/lib/tool-prefix.mjs +226 -0
  109. package/lib/tool-shortlist.mjs +162 -0
  110. package/lib/tools.mjs +2333 -0
  111. package/lib/tsserver.mjs +423 -0
  112. package/lib/turn.mjs +5672 -0
  113. package/lib/untrusted-block.mjs +271 -0
  114. package/lib/verify-claim.mjs +299 -0
  115. package/lib/vision.mjs +330 -0
  116. package/lib/voice-task.mjs +561 -0
  117. package/lib/warm-provider.mjs +255 -0
  118. package/lib/websearch.mjs +401 -0
  119. package/lib/workspace.mjs +928 -0
  120. package/lib/write-approval.mjs +235 -0
  121. package/lib/write-many.mjs +162 -0
  122. package/package.json +62 -0
  123. package/scripts/bundle.mjs +768 -0
  124. package/scripts/cache-floor.mjs +176 -0
  125. package/scripts/machine.mjs +226 -0
  126. package/scripts/test.mjs +139 -0
  127. package/skills/accessibility.md +87 -0
  128. package/skills/acuvo-design-system.md +123 -0
  129. package/skills/animation.md +84 -0
  130. package/skills/api-design.md +82 -0
  131. package/skills/auth-and-sessions.md +78 -0
  132. package/skills/build-with-a-framework.md +101 -0
  133. package/skills/colour-and-contrast.md +112 -0
  134. package/skills/creative-engines.md +81 -0
  135. package/skills/css-layout.md +85 -0
  136. package/skills/data-and-charts.md +77 -0
  137. package/skills/debugging.md +76 -0
  138. package/skills/designing-by-looking.md +84 -0
  139. package/skills/error-handling.md +78 -0
  140. package/skills/forms-and-validation.md +93 -0
  141. package/skills/nextjs-app-router.md +75 -0
  142. package/skills/page-composition.md +103 -0
  143. package/skills/performance.md +77 -0
  144. package/skills/plan-before-building.md +52 -0
  145. package/skills/planning-and-delegating.md +72 -0
  146. package/skills/refactoring.md +70 -0
  147. package/skills/security-basics.md +76 -0
  148. package/skills/state-management.md +73 -0
  149. package/skills/supabase-multitenant.md +72 -0
  150. package/skills/typescript-strict.md +90 -0
  151. package/skills/typography.md +135 -0
  152. package/skills/verify-your-own-work.md +62 -0
  153. package/skills/web-app-quality.md +62 -0
  154. 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`.