ucode-agent 1.0.0 → 1.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.
@@ -1,47 +1,89 @@
1
1
  ---
2
2
  name: debug
3
- description: Find the actual cause of a bug instead of the first plausible one — reproduce it, narrow it, prove the fix, and leave a test behind.
3
+ description: Find and fix the real cause of a bug — reproduce it, narrow it down with evidence, prove the fix, guard it with a test, and check for the same bug elsewhere.
4
+ auto: bug, crash, crashes, crashing, broken, not working, doesn't work, does not work, stack trace, exception, traceback, throws, failing, fails, regression, undefined is not, cannot read properties, 500 error, blank page, hangs, freezes
4
5
  ---
5
6
 
6
7
  # Debugging
7
8
 
8
- The temptation is to read the code, form a theory, change something, and
9
- declare victory when the symptom disappears. That is how a bug gets moved
10
- rather than fixed.
9
+ The temptation is to read the code, form a theory, change something, and call
10
+ it fixed when the symptom goes away. That moves bugs rather than fixing them.
11
+ Work from evidence, in this order.
11
12
 
12
- ## Reproduce it first
13
+ ## 1. Reproduce it yourself
13
14
 
14
- Do not start from the description. Run the thing and see the failure with your
15
- own eyes: the command, the input, the exact error and where it comes from. If
16
- you cannot reproduce it, say so and ask for what you need the input, the
17
- version, the full stack. Guessing from a paraphrase wastes everyone's turn.
15
+ Do not debug from the description. Run it and see it fail: the exact command,
16
+ the input, the full error, the line it comes from. Write down the reproduction
17
+ as a single command or a few steps you will run it again at the end.
18
18
 
19
- ## Narrow before you theorise
19
+ If you cannot reproduce it, say so and ask for exactly what is missing: the
20
+ input, the environment, the version, the full output. Guessing from a
21
+ paraphrase wastes everyone's turn.
20
22
 
21
- - Read the whole stack trace, including the frames you assume are irrelevant.
22
- The top frame is where it surfaced, not necessarily where it went wrong.
23
- - `grep` for the message text to find where it is produced.
24
- - Cut the search space in half at a time: does the smaller input fail? Does it
25
- fail on the previous commit? Does the layer below get the right value?
26
- - Print or log the values at the boundary rather than reasoning about what they
27
- should be. What you believe is in that variable is the thing under suspicion.
23
+ ## 2. Read the whole error
28
24
 
29
- ## Fix the cause
25
+ - The whole stack trace, including frames you assume are irrelevant. The top
26
+ frame is where it surfaced, not necessarily where it went wrong.
27
+ - The first error, not the last. Later errors are often consequences.
28
+ - `grep` for the exact message text to find where it is produced.
29
+ - Check the obvious before the clever: is the file saved, the server restarted,
30
+ the right branch checked out, the env var set, the dependency installed, the
31
+ cache cleared (`.next`, `node_modules/.vite`, `__pycache__`)?
30
32
 
31
- State the cause in one sentence before you change anything: *this value is
32
- undefined here because the caller only sets it on the success path*. If you
33
- cannot write that sentence, you have not found it yet.
33
+ ## 3. Narrow it down
34
34
 
35
- Then fix that, not the symptom. A guard that hides the undefined value leaves
36
- the real defect in place, with one more layer over it.
35
+ Cut the search space in half each step:
37
36
 
38
- ## Prove it
37
+ - **Input:** does a smaller or simpler input still fail? Find the smallest one
38
+ that does.
39
+ - **Code:** comment out or bypass half the path. Does it still fail?
40
+ - **Time:** did it work before? `git log` / `git diff` since then, or
41
+ `git bisect` between a good and a bad commit.
42
+ - **Layer:** is the value right when it enters the function? When it leaves?
43
+ At the API boundary? In the database? Log it at each boundary and look,
44
+ rather than reasoning about what it "should" be.
39
45
 
40
- - Run the original reproduction. It must now pass.
41
- - Run the rest of the tests. A fix that breaks two other things is a trade,
42
- and the user gets to make it, not you.
43
- - Write a test that fails without your fix. A bug with no regression test comes
44
- back.
46
+ The value you are sure about is the one under suspicion. Print it.
45
47
 
46
- Then say what the cause actually was, in one or two sentences. If you fixed
47
- something adjacent along the way, say that too.
48
+ ## 4. Know where bugs usually live
49
+
50
+ - **Async:** a missing `await`, a race between two requests, state read before
51
+ it is set, a promise rejection nobody catches.
52
+ - **State:** stale closures in React effects, mutation of shared objects, a
53
+ cache that was never invalidated.
54
+ - **Boundaries:** off-by-one, empty arrays, `null` vs `undefined` vs `''`,
55
+ timezones, number parsing (`'10' + 1`), float rounding.
56
+ - **Data shape:** the API returned something different from the type — an
57
+ error object, a wrapped payload, a string instead of JSON.
58
+ - **Environment:** missing env var, wrong Node version, path case sensitivity,
59
+ Windows vs POSIX paths and line endings, a port already in use.
60
+ - **Build tooling:** a stale build cache, a server/client boundary violation in
61
+ Next.js, a default vs named export mismatch, ESM vs CommonJS.
62
+
63
+ ## 5. State the cause before fixing it
64
+
65
+ Write it in one sentence: *"`score` is `undefined` here because the parser
66
+ returns `{ data: {...} }` and the component reads `result.score`."* If you
67
+ cannot write that sentence, you have not found the cause yet — keep narrowing.
68
+
69
+ ## 6. Fix the cause, not the symptom
70
+
71
+ A `?.` or a `try/catch` that hides the failure leaves the defect in place under
72
+ one more layer. Fix it where it originates. Keep the change as small as the
73
+ cause allows, and do not refactor unrelated code in the same change.
74
+
75
+ ## 7. Prove it
76
+
77
+ - Run the original reproduction. It must pass now.
78
+ - Run the whole test suite. A fix that breaks two other things is a trade the
79
+ user gets to decide on, not you.
80
+ - Add a regression test that fails without the fix and passes with it — then
81
+ briefly revert the fix to confirm the test really catches it.
82
+ - Look for the same mistake elsewhere: `grep` for the same pattern, call, or
83
+ assumption. Bugs come in families.
84
+
85
+ ## 8. Report
86
+
87
+ The cause in one or two sentences, the fix, how you verified it, and anything
88
+ adjacent you noticed but did not change. If you could not fully confirm it,
89
+ say what is still uncertain.
@@ -0,0 +1,84 @@
1
+ ---
2
+ name: performance
3
+ description: Make software measurably faster — measure first, find the real bottleneck, fix it, and prove the improvement with numbers. Covers web vitals, bundles, React rendering, APIs, databases and Node.
4
+ auto: slow, slower, performance, perf, optimize, optimise, optimization, speed up, faster, lag, laggy, sluggish, bundle size, lighthouse, core web vitals, web vitals, lcp, cls, inp, memory leak, re-render, rerender, n+1, latency, takes too long
5
+ ---
6
+
7
+ # Performance
8
+
9
+ Guessing at performance is how people spend a day optimizing something that
10
+ was never slow. Measure, change one thing, measure again.
11
+
12
+ ## 1. Measure before touching anything
13
+
14
+ - **Define the slow thing precisely**: which page, action or endpoint, how slow
15
+ now, how fast it needs to be.
16
+ - **Get a baseline number** you can re-run:
17
+ - Web page: Lighthouse / PageSpeed (LCP, INP, CLS, total JS), the browser
18
+ Performance panel, `next build` output (per-route JS size).
19
+ - API: time the request (`curl -w "%{time_total}\n"`), log durations per step.
20
+ - Node/Python: a profiler (`node --cpu-prof`, `clinic`, `py-spy`), or timers
21
+ around the suspect code.
22
+ - Database: `EXPLAIN ANALYZE` on the slow query.
23
+ - Measure the production build, not dev mode — dev is deliberately slow.
24
+
25
+ ## 2. Find the actual bottleneck
26
+
27
+ It is almost always one of these, in roughly this order of likelihood:
28
+
29
+ 1. **Network waterfalls** — requests that wait on each other when they could run
30
+ in parallel; data fetched on the client that could be fetched on the server.
31
+ 2. **Too much JavaScript** — heavy dependencies, everything marked
32
+ `"use client"`, no code splitting.
33
+ 3. **Unoptimized images and fonts** — huge images, no dimensions (layout shift),
34
+ blocking font loads.
35
+ 4. **Database** — N+1 queries, missing indexes, fetching whole tables, no
36
+ pagination.
37
+ 5. **Rendering** — React re-rendering large trees on every keystroke, expensive
38
+ work inside render, long lists without virtualization.
39
+ 6. **Algorithmic** — nested loops over large data, repeated work that could be
40
+ cached or computed once.
41
+
42
+ ## 3. Fixes by area
43
+
44
+ **Web (Next.js / React)**
45
+ - Server components by default; `"use client"` at the leaves only.
46
+ - `next/image` with explicit sizes; `priority` on the LCP image; modern formats.
47
+ - `next/font` with `display: swap`, only the weights used.
48
+ - Dynamic `import()` for heavy, below-the-fold or rarely used components.
49
+ - Replace heavy libraries (moment → date-fns/Intl, lodash → native, big chart
50
+ libs → lighter ones) and check the per-route JS in the build output.
51
+ - Parallelize independent fetches with `Promise.all`; stream with `Suspense`.
52
+ - Cache: static where possible, `revalidate` for data that changes slowly.
53
+
54
+ **React rendering**
55
+ - Keep state as low in the tree as possible; lift only what must be shared.
56
+ - Stable props: memoize expensive values and callbacks passed to memoized
57
+ children — but only where the profiler shows a real cost.
58
+ - Virtualize lists over a few hundred rows.
59
+ - Debounce input-driven work (search, validation) at ~200–300ms.
60
+
61
+ **APIs and databases**
62
+ - Index columns used in `WHERE`, `JOIN` and `ORDER BY`; confirm with `EXPLAIN`.
63
+ - Batch or join instead of querying in a loop (N+1).
64
+ - Select only the columns needed; paginate everything user-sized.
65
+ - Cache expensive, repeatable results (in memory, Redis, HTTP caching) with a
66
+ clear invalidation rule.
67
+ - Move slow non-essential work (emails, analytics, thumbnails) to a background
68
+ job.
69
+
70
+ **Node**
71
+ - Never block the event loop with sync I/O or heavy CPU in a request handler.
72
+ - Stream large files instead of reading them whole.
73
+ - Reuse clients and connections (DB pools, HTTP keep-alive).
74
+
75
+ ## 4. Change one thing at a time, and prove it
76
+
77
+ After each change, re-run the same measurement. Keep changes that move the
78
+ number; revert ones that do not — complexity without a measured win is a cost.
79
+
80
+ ## 5. Report with numbers
81
+
82
+ Before and after for each metric that changed ("LCP 4.1s → 1.6s, route JS
83
+ 312 kB → 148 kB"), what caused it, and anything left that would need a bigger
84
+ change to fix.
@@ -0,0 +1,72 @@
1
+ ---
2
+ name: refactor
3
+ description: Restructure code without changing what it does — a safety net first, small verified steps, clear boundaries and names, and no behaviour change slipped in along the way.
4
+ auto: refactor, refactoring, clean up, cleanup, clean this, restructure, reorganize, reorganise, simplify, tech debt, technical debt, extract, split this file, split up, dead code, duplicate code, duplication, messy code, spaghetti
5
+ ---
6
+
7
+ # Refactoring
8
+
9
+ A refactor changes the shape of code and nothing else. The moment behaviour
10
+ changes, it is a rewrite, and a rewrite hidden inside a refactor is how
11
+ regressions ship with nobody noticing.
12
+
13
+ ## 1. Know why, and where it stops
14
+
15
+ - State the goal in one line: *split the 700-line page into components*,
16
+ *remove the duplicated fetch logic*, *make the scoring rules testable*.
17
+ - State the boundary: which files are in scope. Resist improving everything you
18
+ pass on the way — note it and leave it.
19
+
20
+ ## 2. Build the safety net first
21
+
22
+ - Run the existing tests and record the result. If there are none around the
23
+ code you are changing, **write characterization tests first**: tests that pin
24
+ down what the code does now, including its odd behaviour. You are preserving
25
+ behaviour, so you must be able to detect when it changes.
26
+ - For UI with no tests, capture the current behaviour: what renders in each
27
+ state, what each control does.
28
+
29
+ ## 3. Read it all before moving anything
30
+
31
+ Read every file in scope in full, and find every caller of what you will change
32
+ (`grep` for the names, the imports, the routes). A rename that misses one
33
+ dynamic reference is a runtime error waiting for the one path nobody tested.
34
+
35
+ ## 4. Small steps, each one green
36
+
37
+ Do one kind of change at a time, and run the tests after each:
38
+
39
+ - **Rename** to say what things are: `data` → `analysis`, `handle()` →
40
+ `submitLabel()`. Names are most of readability.
41
+ - **Extract** a function or component for each distinct job; a function should
42
+ do one thing at one level of abstraction.
43
+ - **Move** code next to what uses it: feature folders over type folders.
44
+ - **Remove duplication** only when the copies really are the same concept —
45
+ two similar-looking pieces that change for different reasons should stay two.
46
+ - **Delete dead code** — unused exports, unreachable branches, commented-out
47
+ blocks. Confirm it is unused with a search first.
48
+ - **Simplify conditionals**: early returns over nesting, lookup tables over long
49
+ `if/else` chains, named booleans over complex expressions.
50
+ - **Push side effects to the edges**: pure logic in the middle (easy to test),
51
+ I/O at the boundary.
52
+
53
+ Use `multi_edit` for several changes in one file, and keep each step small
54
+ enough that a failing test points straight at the cause.
55
+
56
+ ## 5. Keep behaviour identical
57
+
58
+ - Same inputs, same outputs, same errors, same side effects, same order of
59
+ side effects.
60
+ - Public APIs and stored formats unchanged, or every caller and every stored
61
+ record updated in the same change.
62
+ - If you find a bug while refactoring, **do not fix it silently inside the
63
+ refactor**. Finish the refactor, then fix the bug as its own change — or
64
+ report it — so each can be reviewed and reverted on its own.
65
+
66
+ ## 6. Finish
67
+
68
+ - All tests pass, the build passes, the linter and type checker are clean.
69
+ - The code is measurably simpler: fewer lines, fewer branches, smaller files,
70
+ clearer names — say which.
71
+ - Report what moved where, anything you noticed but deliberately left alone,
72
+ and any behaviour you had to pin down with new tests.
@@ -0,0 +1,110 @@
1
+ ---
2
+ name: security
3
+ description: Build and audit software so it is safe by default — secrets, authentication and authorization, input validation, injection, XSS, CSRF, SSRF, uploads, dependencies and headers, checked against how attacks actually happen.
4
+ auto: security, secure, vulnerability, vulnerabilities, auth, authentication, authorization, login, sign in, signup, sign up, password, passwords, jwt, oauth, session cookie, xss, csrf, ssrf, sql injection, injection, secrets, api key, api keys, owasp, harden, hardening, permissions, rate limit
5
+ ---
6
+
7
+ # Security
8
+
9
+ Assume every input is hostile and every secret will be looked for. Most real
10
+ breaches come from a short list of boring mistakes; this skill is that list,
11
+ with what to do about each.
12
+
13
+ ## 1. Secrets
14
+
15
+ - **Never in the browser.** Anything imported by client code ships to every
16
+ visitor — including a "temporary" hardcoded key. Keys live in server routes,
17
+ server actions or server-only modules (`import 'server-only'`).
18
+ - **Never in the repository.** Use `.env.local` / `.env` (gitignored) and commit
19
+ a `.env.example` with placeholders. If a key was ever committed or pasted
20
+ somewhere public, rotate it — deleting the line does not un-leak it.
21
+ - **Never in logs, errors or URLs.** Redact before logging; do not put tokens
22
+ in query strings.
23
+ - If the user insists on hardcoding a key for now, put it in one server-only
24
+ file, say exactly where it is, and recommend moving it to an env var.
25
+
26
+ ## 2. Authentication
27
+
28
+ - Use a proven library or provider (Auth.js/NextAuth, Clerk, Supabase Auth,
29
+ Lucia-style patterns) rather than hand-rolled sessions and hashing.
30
+ - Passwords: argon2id or bcrypt, never reversible, never logged. Rate-limit
31
+ login and reset endpoints. Same error message for "no such user" and "wrong
32
+ password".
33
+ - Sessions: `HttpOnly`, `Secure`, `SameSite=Lax` (or `Strict`) cookies. Rotate
34
+ the session on login. Expire idle sessions.
35
+ - JWTs: short expiry, verify signature and algorithm server-side, never trust
36
+ claims the client can edit.
37
+
38
+ ## 3. Authorization — the most common real hole
39
+
40
+ - **Check ownership on every request**, on the server, for every object:
41
+ `WHERE id = $1 AND user_id = $session.user`. Changing an ID in a URL or body
42
+ must never reveal someone else's data (IDOR).
43
+ - Deny by default. Every route states who may call it.
44
+ - Hiding a button is not authorization; the endpoint behind it must check too.
45
+
46
+ ## 4. Input validation and injection
47
+
48
+ - Validate every input at the boundary with a schema (zod, pydantic): type,
49
+ length, range, format. Reject, do not "clean".
50
+ - **SQL:** parameterized queries or an ORM only. Never string-build SQL with
51
+ user input.
52
+ - **Shell:** avoid it; if unavoidable, pass arguments as an array
53
+ (`execFile`, `spawn` without `shell: true`), never interpolate.
54
+ - **Paths:** resolve and verify the result stays inside the allowed directory;
55
+ reject `..` and absolute paths from users.
56
+ - **SSRF:** when fetching a user-supplied URL, allow-list hosts, block private
57
+ and link-local ranges (127.0.0.0/8, 10/8, 172.16/12, 192.168/16, 169.254/16,
58
+ ::1), and do not follow redirects blindly.
59
+
60
+ ## 5. Output: XSS
61
+
62
+ - Let the framework escape (React, templating engines). Treat
63
+ `dangerouslySetInnerHTML`, `innerHTML`, `v-html` and markdown-to-HTML as
64
+ red flags: sanitize with DOMPurify if you must render HTML.
65
+ - Never put user input into `href` without checking the scheme
66
+ (`javascript:` URLs), or into inline `<script>` or event handlers.
67
+ - Set a Content-Security-Policy where you can.
68
+
69
+ ## 6. Requests
70
+
71
+ - **CSRF:** SameSite cookies plus a CSRF token or origin check on state-changing
72
+ requests that use cookie auth. Next.js server actions check origin; custom
73
+ routes need it done.
74
+ - **CORS:** never `*` with credentials; allow-list the origins that need it.
75
+ - **Rate limiting** on login, signup, password reset, and any expensive or paid
76
+ endpoint (AI calls especially) — per IP and per user.
77
+
78
+ ## 7. File uploads
79
+
80
+ - Check type by content (magic bytes), not just the extension or MIME header.
81
+ - Enforce a size limit on the server, not only the client.
82
+ - Store outside the web root or in object storage with generated names; never
83
+ execute or serve uploads from the app's own origin as HTML.
84
+ - Strip metadata (EXIF location) from images when privacy matters.
85
+
86
+ ## 8. Errors, headers, dependencies
87
+
88
+ - Errors to users are generic; details go to server logs. No stack traces in
89
+ responses.
90
+ - Headers: `Strict-Transport-Security`, `X-Content-Type-Options: nosniff`,
91
+ `Referrer-Policy: strict-origin-when-cross-origin`, `frame-ancestors` via CSP.
92
+ - Dependencies: `npm audit` (or the ecosystem equivalent), remove unused
93
+ packages, pin versions with a lockfile, be wary of new packages with few
94
+ downloads or typo-like names.
95
+
96
+ ## 9. Auditing existing code
97
+
98
+ Search rather than read everything:
99
+
100
+ ```
101
+ grep for: api[_-]?key|secret|token|password (hardcoded secrets)
102
+ dangerouslySetInnerHTML|innerHTML|eval\(|new Function
103
+ exec\(|execSync|shell: true|child_process
104
+ \$\{.*\}.*(SELECT|INSERT|UPDATE|DELETE) (string-built SQL)
105
+ fetch\(.*req\.|axios\(.*req\. (user-controlled URLs)
106
+ ```
107
+
108
+ Then check every route for authentication and ownership checks. Report
109
+ findings ranked by severity with the file, the attack, and the fix — and fix
110
+ the critical ones first if asked to fix.