@sentry/warden 0.24.1 → 0.26.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/.cursor/mcp.json +7 -0
- package/CHANGELOG.md +454 -0
- package/README.md +2 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +9 -4
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +2 -1
- package/dist/cli/help.js.map +1 -1
- package/dist/config/loader.d.ts +7 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +32 -8
- package/dist/config/loader.js.map +1 -1
- package/dist/sentry.d.ts +4 -0
- package/dist/sentry.d.ts.map +1 -1
- package/dist/sentry.js +14 -0
- package/dist/sentry.js.map +1 -1
- package/package.json +1 -1
- package/src/builtin-skills/code-review/SKILL.md +85 -0
- package/src/builtin-skills/code-review/SOURCES.md +42 -0
- package/src/builtin-skills/code-review/SPEC.md +110 -0
- package/src/builtin-skills/code-review/references/github-workflows.md +88 -0
- package/src/builtin-skills/code-review/references/javascript-typescript.md +73 -0
- package/src/builtin-skills/code-review/references/python.md +77 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# JavaScript And TypeScript Bug Review Notes
|
|
2
|
+
|
|
3
|
+
Use this when reviewing JavaScript, TypeScript, Node, React, Next.js, or browser code. These notes refine the core `code-review` skill; they do not add style, architecture, security, or performance-only scope.
|
|
4
|
+
|
|
5
|
+
## Runtime Boundaries
|
|
6
|
+
|
|
7
|
+
- TypeScript types disappear at runtime. Treat JSON, form data, URL params, cookies, local storage, external API responses, database rows, env vars, and message payloads as untrusted shape until parsed or validated.
|
|
8
|
+
- `as`, `!`, `any`, unchecked indexed access, and broad generics are leads, not findings. Report only when a reachable runtime value can violate the assumption.
|
|
9
|
+
- Generated types, Zod schemas, tRPC routers, OpenAPI clients, GraphQL fragments, ORM models, and serializer tests can prove the intended contract. Read them before reporting a mismatch.
|
|
10
|
+
- React and Next.js can split server and client execution. Verify where the code actually runs before claiming a browser, server, hydration, or serialization bug.
|
|
11
|
+
|
|
12
|
+
## High-Signal Patterns
|
|
13
|
+
|
|
14
|
+
| Pattern | Bug Shape | Safer Shape |
|
|
15
|
+
|---------|-----------|-------------|
|
|
16
|
+
| Falsey fallback | `value || defaultValue` treats `0`, `false`, or `""` as absent when those are valid values. | Use `??` or explicit presence checks. |
|
|
17
|
+
| Dropped async work | `forEach(async ...)`, `items.map(async ...)` without `await Promise.all`, missing `return` in promise chains, or fire-and-forget work inside request/CLI paths. | Await the work, return the promise, or intentionally detach with error handling. |
|
|
18
|
+
| Swallowed async errors | `void fn()`, unhandled promise callbacks, or catch blocks convert failed writes to success responses. | Await and propagate errors, or surface partial failure explicitly. |
|
|
19
|
+
| State mutation | In-place `sort`, `reverse`, `splice`, object mutation, cache mutation, or prop mutation changes data later reused by callers. | Clone before mutation or keep mutation local to newly created values. |
|
|
20
|
+
| Stale React state | Closures, effects, memoization, or callbacks use stale props/state and produce wrong UI or wrong submitted data. | Use correct dependencies, functional updates, refs for mutable external state, or derive state at render time. |
|
|
21
|
+
| Schema drift | Runtime schema, inferred type, serialized payload, or API response changed without matching callers. | Update schema and every consumer, or keep backward-compatible fields. |
|
|
22
|
+
| Pagination and ordering | Filtering after slicing, unstable sort keys, cursor fields that are not unique, or changed default order skips or duplicates records. | Filter before paging, add deterministic tie-breakers, and preserve cursor contracts. |
|
|
23
|
+
| Date and precision | Date-only strings, local timezone parsing, DST boundaries, milliseconds vs seconds, integer rounding, or currency precision changes produce wrong values. | Normalize units and timezones at boundaries and keep decimal math explicit. |
|
|
24
|
+
| Import/export breakage | A value import points at a type-only export, a default import targets named exports, or an ESM/CJS boundary no longer matches runtime output. | Use `export type` for types and value exports for runtime symbols, matching the package format. |
|
|
25
|
+
| Cleanup and cancellation | Abort handlers, timers, subscriptions, streams, temp files, or locks are not cleaned up on error or unmount. | Use finally blocks, cleanup functions, abort propagation, and scoped resource ownership. |
|
|
26
|
+
|
|
27
|
+
## False-Positive Controls
|
|
28
|
+
|
|
29
|
+
- `Promise.all`, `Promise.allSettled`, returned promise chains, and framework-managed async handlers can prove async work is awaited.
|
|
30
|
+
- `value ?? defaultValue` preserves `0`, `false`, and `""`; do not report falsey collapse there.
|
|
31
|
+
- In-place mutation is safe when the array or object was created locally and is not reused by callers.
|
|
32
|
+
- Optional chaining is not a bug when downstream code intentionally handles absence.
|
|
33
|
+
- Type assertions are safe when the value comes from a checked schema, trusted factory, or exhaustive discriminated union.
|
|
34
|
+
- React hook dependency warnings are not findings by themselves. Show the stale value and user-visible wrong behavior.
|
|
35
|
+
- TypeScript compile errors are findings only when the changed code deterministically breaks the build or emitted runtime behavior.
|
|
36
|
+
|
|
37
|
+
## Minimal Examples
|
|
38
|
+
|
|
39
|
+
**Report: falsey value regression**
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
const limit = Number(searchParams.get("limit")) || 50;
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
If `limit=0` is a documented way to disable fetching, this turns a valid value into `50`.
|
|
46
|
+
|
|
47
|
+
**Report: dropped async writes**
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
users.forEach(async (user) => {
|
|
51
|
+
await sendInvite(user.id);
|
|
52
|
+
});
|
|
53
|
+
return { sent: users.length };
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The function reports success before invites finish, and failures are detached from the response.
|
|
57
|
+
|
|
58
|
+
**Report: schema drift**
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
const UserResponse = z.object({ id: z.string(), name: z.string() });
|
|
62
|
+
return { id: user.id, displayName: user.name };
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The returned payload no longer satisfies the runtime schema or callers expecting `name`.
|
|
66
|
+
|
|
67
|
+
**Do not report: awaited async map**
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
await Promise.all(users.map((user) => sendInvite(user.id)));
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The promises are joined and errors propagate through the awaited call.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Python Bug Review Notes
|
|
2
|
+
|
|
3
|
+
Use this when reviewing Python, Django, Flask, FastAPI, Celery, or Python service code. These notes refine the core `code-review` skill; they do not add style, architecture, security, or performance-only scope.
|
|
4
|
+
|
|
5
|
+
## Runtime Boundaries
|
|
6
|
+
|
|
7
|
+
- Type hints are not runtime validation. Treat request data, query params, env vars, external API responses, database rows, task payloads, and deserialized files as shape-unknown until validated.
|
|
8
|
+
- Pydantic models, DRF serializers, dataclasses, typed dicts, Django model fields, migrations, and existing tests can prove the intended contract. Read them before reporting a mismatch.
|
|
9
|
+
- Decorators and framework hooks can change call order, transaction scope, auth context, and exception behavior. Verify the effective path.
|
|
10
|
+
- Background tasks and management commands often run outside request transactions and sessions. Check idempotency, tenant/account context, and retry behavior before reporting.
|
|
11
|
+
|
|
12
|
+
## High-Signal Patterns
|
|
13
|
+
|
|
14
|
+
| Pattern | Bug Shape | Safer Shape |
|
|
15
|
+
|---------|-----------|-------------|
|
|
16
|
+
| Mutable defaults | Function, dataclass, or model defaults reuse lists, dicts, sets, or objects across calls or instances. | Use `None` plus initialization, `default_factory`, or framework-specific callable defaults. |
|
|
17
|
+
| Falsey fallback | `value or default` treats `0`, `False`, or `""` as absent when those are valid values. | Check `is None`, missing keys, or explicit sentinel values. |
|
|
18
|
+
| Missing `None` handling | `.first()`, `.get()`, optional config, env values, cache reads, or external responses are dereferenced without proving presence. | Add explicit absence handling or enforce presence at the boundary. |
|
|
19
|
+
| Swallowed errors | Broad `except` returns success, empty data, or partial defaults that callers treat as complete. | Propagate failure, return explicit partial state, or compensate rolled-back work. |
|
|
20
|
+
| Transaction gaps | Multiple writes, task enqueues, cache updates, or file operations can partially succeed when a later step fails. | Use transactions, `on_commit`, idempotency keys, or compensation. |
|
|
21
|
+
| Async mismatch | Coroutine is not awaited, blocking I/O runs in an async endpoint, or async context managers are entered incorrectly. | Await coroutines, use async clients, and keep blocking work out of event-loop paths. |
|
|
22
|
+
| Iterator exhaustion | Generators, queryset iterators, request streams, or file objects are consumed once and then reused as if still populated. | Materialize intentionally or pass a fresh iterator/stream. |
|
|
23
|
+
| Timezone and precision | Naive and aware datetimes are mixed, date boundaries use server local time, or decimal money is converted to float. | Normalize timezone and use `Decimal` or integer minor units for money. |
|
|
24
|
+
| Query and migration drift | Renamed fields, changed defaults, non-null constraints, data migrations, or backfills miss existing rows or write wrong records. | Include backward-compatible migrations and scoped update filters. |
|
|
25
|
+
| Task retry side effects | Celery or queue retries duplicate emails, charges, state transitions, or external calls. | Make side effects idempotent or persist completion before retryable boundaries. |
|
|
26
|
+
|
|
27
|
+
## False-Positive Controls
|
|
28
|
+
|
|
29
|
+
- Django ORM, SQLAlchemy, and Pydantic can enforce contracts. Verify the exact model, serializer, or schema before reporting.
|
|
30
|
+
- `get_or_create`, `update_or_create`, database constraints, and transactions can mitigate duplicate or partial-write paths.
|
|
31
|
+
- A broad `except` is not a finding if the caller receives explicit failure state and no partial success is claimed.
|
|
32
|
+
- Mutable values are safe when created inside the function or supplied by a documented immutable factory.
|
|
33
|
+
- QuerySet laziness is not a bug by itself. Show the changed evaluation order that produces wrong data.
|
|
34
|
+
- Type-checker-only issues are findings only when they deterministically break runtime behavior, packaging, or CI.
|
|
35
|
+
|
|
36
|
+
## Minimal Examples
|
|
37
|
+
|
|
38
|
+
**Report: mutable default**
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
def collect_errors(error, bucket=[]):
|
|
42
|
+
bucket.append(error)
|
|
43
|
+
return bucket
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Every call shares the same list, so unrelated requests can see stale errors.
|
|
47
|
+
|
|
48
|
+
**Report: swallowed partial failure**
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
try:
|
|
52
|
+
charge_customer(invoice)
|
|
53
|
+
mark_paid(invoice)
|
|
54
|
+
except Exception:
|
|
55
|
+
return {"ok": True}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The caller receives success even if charging or persistence failed.
|
|
59
|
+
|
|
60
|
+
**Report: missing absence handling**
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
profile = Profile.objects.filter(user_id=user_id).first()
|
|
64
|
+
return profile.timezone
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
If profiles are optional or not yet created, this crashes instead of following the expected fallback.
|
|
68
|
+
|
|
69
|
+
**Do not report: dataclass default factory**
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
@dataclass
|
|
73
|
+
class Batch:
|
|
74
|
+
items: list[str] = field(default_factory=list)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Each instance receives a fresh list.
|