@wrongstack/core 0.255.0 → 0.256.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/dist/{agent-bridge-l_DsFEbr.d.ts → agent-bridge-BrxWHEOm.d.ts} +1 -1
- package/dist/{agent-subagent-runner-DhYLgAJo.d.ts → agent-subagent-runner-US741uBH.d.ts} +17 -8
- package/dist/{brain-BaQsRNka.d.ts → brain-TjEEwSpw.d.ts} +1 -1
- package/dist/{compactor-BRfg3QPd.d.ts → compactor-C5sT4U7I.d.ts} +1 -1
- package/dist/{config-eSsrto5d.d.ts → config-DuAu23zm.d.ts} +16 -1
- package/dist/{context-CLz3z_E8.d.ts → context-CGdgA0q6.d.ts} +13 -0
- package/dist/coordination/index.d.ts +14 -14
- package/dist/coordination/index.js +21 -2
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +25 -25
- package/dist/defaults/index.js +238 -42
- package/dist/defaults/index.js.map +1 -1
- package/dist/execution/index.d.ts +15 -15
- package/dist/execution/index.js +121 -22
- package/dist/execution/index.js.map +1 -1
- package/dist/execution/prompt-enhancer.d.ts +1 -1
- package/dist/extension/index.d.ts +6 -6
- package/dist/{goal-preamble-BgoPmZ8l.d.ts → goal-preamble-UiEkbNmW.d.ts} +21 -10
- package/dist/{index-BilZMsOK.d.ts → index-CC0Mcm05.d.ts} +9 -9
- package/dist/{index-Csoc_bKs.d.ts → index-CitPrI3a.d.ts} +20 -7
- package/dist/index.d.ts +112 -42
- package/dist/index.js +609 -111
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +6 -6
- package/dist/kernel/index.d.ts +10 -10
- package/dist/{llm-selector-D22R4AFz.d.ts → llm-selector-CJ4SyAFE.d.ts} +2 -2
- package/dist/{mcp-servers-DfXxCASH.d.ts → mcp-servers-D8YnLaEp.d.ts} +3 -3
- package/dist/models/index.d.ts +5 -5
- package/dist/{models-registry-DpanBg8D.d.ts → models-registry-ByZCdFuQ.d.ts} +1 -1
- package/dist/{multi-agent-coordinator-Bs-M0Mo6.d.ts → multi-agent-coordinator-DqTUEAeC.d.ts} +1 -1
- package/dist/{null-fleet-bus-CWdU1_cO.d.ts → null-fleet-bus-B5mfTJXT.d.ts} +17 -6
- package/dist/observability/index.d.ts +2 -2
- package/dist/{package-outdated-watcher-Dz-eNZlQ.d.ts → package-outdated-watcher-BSgR_kK-.d.ts} +3 -3
- package/dist/{parallel-eternal-engine-CAMabk-X.d.ts → parallel-eternal-engine-C0juOszP.d.ts} +24 -10
- package/dist/{path-resolver-B7VjhUHq.d.ts → path-resolver-CbkT-RMU.d.ts} +3 -3
- package/dist/{permission-DbWPbuoA.d.ts → permission-CwBBpCoF.d.ts} +1 -1
- package/dist/{permission-policy-AOk0LVsV.d.ts → permission-policy-B8rSu908.d.ts} +39 -2
- package/dist/{pipeline-Bxa3wDcy.d.ts → pipeline-JG8XoudC.d.ts} +2 -2
- package/dist/{plan-templates-D3guWwTi.d.ts → plan-templates-DPiQMkBz.d.ts} +5 -5
- package/dist/{provider-runner-C8_e4Lo1.d.ts → provider-runner-hM7EXlLI.d.ts} +3 -3
- package/dist/{retry-policy-BVnkbMET.d.ts → retry-policy-Tg7LXkoK.d.ts} +1 -1
- package/dist/sdd/index.d.ts +8 -8
- package/dist/{secret-vault-CeVNiy_f.d.ts → secret-vault-BkYkJWQs.d.ts} +1 -1
- package/dist/security/index.d.ts +4 -4
- package/dist/security/index.js +89 -18
- package/dist/security/index.js.map +1 -1
- package/dist/{selector-Cb4_9-hf.d.ts → selector-DWsqVjGf.d.ts} +1 -1
- package/dist/{session-event-bridge-BhtkkFFy.d.ts → session-event-bridge-BAFWdgQ3.d.ts} +1 -1
- package/dist/{session-reader-CCOssnBS.d.ts → session-reader-CqRvaL5v.d.ts} +1 -1
- package/dist/{skill-Bj6Ezqb8.d.ts → skill-DGIXCtdv.d.ts} +6 -0
- package/dist/skills/index.d.ts +1 -1
- package/dist/storage/index.d.ts +10 -10
- package/dist/storage/index.js +8 -1
- package/dist/storage/index.js.map +1 -1
- package/dist/types/index.d.ts +19 -19
- package/dist/types/index.js +83 -25
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +2 -2
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/api-design/SKILL.md +1 -0
- package/skills/api-design/SKILL.save.md +26 -0
- package/skills/audit-log/SKILL.md +9 -2
- package/skills/audit-log/SKILL.save.md +22 -0
- package/skills/bug-hunter/SKILL.md +10 -2
- package/skills/bug-hunter/SKILL.save.md +33 -0
- package/skills/chimera/SKILL.md +12 -18
- package/skills/chimera/SKILL.save.md +26 -0
- package/skills/docker-deploy/SKILL.md +1 -0
- package/skills/docker-deploy/SKILL.save.md +23 -0
- package/skills/git-flow/SKILL.md +23 -2
- package/skills/git-flow/SKILL.save.md +25 -0
- package/skills/multi-agent/SKILL.md +23 -2
- package/skills/multi-agent/SKILL.save.md +26 -0
- package/skills/node-modern/SKILL.md +2 -1
- package/skills/node-modern/SKILL.save.md +21 -0
- package/skills/observability/SKILL.md +1 -0
- package/skills/observability/SKILL.save.md +34 -0
- package/skills/output-standards/SKILL.md +133 -0
- package/skills/output-standards/SKILL.save.md +21 -0
- package/skills/prompt-engineering/SKILL.md +2 -1
- package/skills/prompt-engineering/SKILL.save.md +29 -0
- package/skills/react-modern/SKILL.md +2 -1
- package/skills/react-modern/SKILL.save.md +24 -0
- package/skills/refactor-planner/SKILL.md +9 -2
- package/skills/refactor-planner/SKILL.save.md +26 -0
- package/skills/research-web/SKILL.md +1 -0
- package/skills/research-web/SKILL.save.md +25 -0
- package/skills/sdd/SKILL.md +2 -1
- package/skills/sdd/SKILL.save.md +19 -0
- package/skills/security-scanner/SKILL.md +10 -3
- package/skills/security-scanner/SKILL.save.md +23 -0
- package/skills/skill-creator/SKILL.md +2 -1
- package/skills/skill-creator/SKILL.save.md +20 -0
- package/skills/tech-stack/SKILL.md +13 -226
- package/skills/tech-stack/SKILL.save.md +25 -0
- package/skills/testing/SKILL.md +1 -0
- package/skills/testing/SKILL.save.md +22 -0
- package/skills/typescript-strict/SKILL.md +2 -1
- package/skills/typescript-strict/SKILL.save.md +19 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Prompt Engineering — WrongStack (Compact)
|
|
2
|
+
|
|
3
|
+
Designs, critiques, and fixes system prompts, tool descriptions, and skill definitions.
|
|
4
|
+
|
|
5
|
+
## Rules
|
|
6
|
+
|
|
7
|
+
1. Static content first, volatile last — cache-friendly prompts cost less.
|
|
8
|
+
2. First sentence of skill description = trigger — keep it specific.
|
|
9
|
+
3. Tool descriptions must say: when to use, key parameters, what it returns.
|
|
10
|
+
4. Remove filler ("Please be helpful", "Sure, I'd be happy to") — wastes tokens.
|
|
11
|
+
5. Always read before edit — agents should read first, then edit.
|
|
12
|
+
|
|
13
|
+
## WrongStack's 4-layer prompt structure
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
Layer 1: Identity — Who you are (static, cacheable)
|
|
17
|
+
Layer 2: Tool usage — Tools and usage hints (static)
|
|
18
|
+
Layer 3: Environment — Context, skills, modes (semistatic)
|
|
19
|
+
Layer 4: Volatile — Session state, errors, mode prompt (dynamic)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Anti-patterns
|
|
23
|
+
|
|
24
|
+
| Anti-pattern | Fix |
|
|
25
|
+
|--------------|-----|
|
|
26
|
+
| "Please be helpful" | Remove it |
|
|
27
|
+
| Vague parameter docs | Add concrete examples |
|
|
28
|
+
| Long preamble | Put question first |
|
|
29
|
+
| Ambiguous pronouns | Name the specific thing |
|
|
@@ -208,4 +208,5 @@ const inputRef = useRef<HTMLInputElement>(null);
|
|
|
208
208
|
|
|
209
209
|
- `typescript-strict` — for TypeScript patterns
|
|
210
210
|
- `node-modern` — for React server components with Node.js
|
|
211
|
-
- `bug-hunter` — for React-specific bugs (stale closures, memory leaks)
|
|
211
|
+
- `bug-hunter` — for React-specific bugs (stale closures, memory leaks)
|
|
212
|
+
- `output-standards` — for standardized `<next_steps>` formatting
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Modern React (19+) — WrongStack (Compact)
|
|
2
|
+
|
|
3
|
+
React 19+ patterns: Server Components by default, `use` hook for promises, clean client boundary management.
|
|
4
|
+
|
|
5
|
+
## Rules
|
|
6
|
+
|
|
7
|
+
1. Default to Server Components — mark `'use client'` only for interactive code.
|
|
8
|
+
2. Keep the client boundary minimal.
|
|
9
|
+
3. Don't use `useEffect` for data fetching — use Server Components or `use(promise)`.
|
|
10
|
+
4. Don't use `forwardRef` in new code — `ref` is a regular prop in React 19.
|
|
11
|
+
5. Use named exports for components.
|
|
12
|
+
6. Event handlers must have explicit types: `React.MouseEvent<HTMLButtonElement>`.
|
|
13
|
+
|
|
14
|
+
## Hook guide
|
|
15
|
+
|
|
16
|
+
| Hook | When to use | Anti-pattern |
|
|
17
|
+
|------|-------------|--------------|
|
|
18
|
+
| `useState` | Local state | Don't sync with props via useEffect |
|
|
19
|
+
| `useTransition` | Non-blocking updates | Don't use for urgent changes |
|
|
20
|
+
| `useDeferredValue` | Deferring expensive rendering | Don't use for simple state |
|
|
21
|
+
| `useCallback` | Stable function refs for deps | Don't memoize everything |
|
|
22
|
+
| `useMemo` | Expensive computations | Don't memoize trivial calcs |
|
|
23
|
+
| `use` | Awaiting promises in render | Only in component render |
|
|
24
|
+
| `useEffect` | Side effects only | Not for data fetching |
|
|
@@ -4,7 +4,7 @@ description: |
|
|
|
4
4
|
Use this skill when planning a multi-file refactor, code modernization,
|
|
5
5
|
or technical debt resolution in WrongStack. Triggers: user says "refactor",
|
|
6
6
|
"technical debt", "modernize", "clean up", "restructure", "decompose".
|
|
7
|
-
version: 1.
|
|
7
|
+
version: 1.2.0
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# Refactor Planner — WrongStack
|
|
@@ -155,6 +155,12 @@ config.ts → logger.ts → path-resolver.ts
|
|
|
155
155
|
- [ ] All Phase 1 tasks pass `pnpm test`
|
|
156
156
|
- [ ] No circular deps in `src/core`
|
|
157
157
|
- [ ] `Context` interface < 20 methods
|
|
158
|
+
|
|
159
|
+
<next_steps>
|
|
160
|
+
1. [Phase 1] Extract `ToolExecutor` interface in core/tool-executor.ts
|
|
161
|
+
2. [Phase 1] Decouple `SessionStore` from Agent in core/session-store.ts
|
|
162
|
+
3. [Phase 2] Break circular dep: Config ↔ Logger in core/config.ts
|
|
163
|
+
</next_steps>
|
|
158
164
|
```
|
|
159
165
|
|
|
160
166
|
## Anti-patterns
|
|
@@ -169,4 +175,5 @@ config.ts → logger.ts → path-resolver.ts
|
|
|
169
175
|
|
|
170
176
|
- `bug-hunter` — for finding bugs exposed by the refactor
|
|
171
177
|
- `git-flow` — for committing each phase properly
|
|
172
|
-
- `multi-agent` — for parallel analysis of multiple modules
|
|
178
|
+
- `multi-agent` — for parallel analysis of multiple modules
|
|
179
|
+
- `output-standards` — for standardized `<next_steps>` formatting
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Refactor Planner — WrongStack (Compact)
|
|
2
|
+
|
|
3
|
+
Analyzes code structure and produces a phased refactoring plan with risk assessment, dependency ordering, and rollback strategy.
|
|
4
|
+
|
|
5
|
+
## Rules
|
|
6
|
+
|
|
7
|
+
1. Always build a dependency graph before planning.
|
|
8
|
+
2. Always include a rollback strategy — every refactor can fail.
|
|
9
|
+
3. Never skip Phase 1 (low-risk quick wins) — momentum matters.
|
|
10
|
+
4. Never over-phase — if a task takes <1h, merge it.
|
|
11
|
+
5. Rate each module by: cyclomatic complexity, test coverage, fan-out, public API surface.
|
|
12
|
+
|
|
13
|
+
## Risk criteria
|
|
14
|
+
|
|
15
|
+
| Factor | Low | Medium | High |
|
|
16
|
+
|--------|-----|--------|------|
|
|
17
|
+
| Cyclomatic complexity | <10 | 10-20 | >20 |
|
|
18
|
+
| Test coverage | >80% | 50-80% | <50% |
|
|
19
|
+
| Fan-out | <5 | 5-15 | >15 |
|
|
20
|
+
| Public API | unchanged | modified | removed |
|
|
21
|
+
|
|
22
|
+
## Phase structure
|
|
23
|
+
|
|
24
|
+
1. **Low Risk / High Payoff**: No behavior change, tests already pass.
|
|
25
|
+
2. **Medium Risk**: Test heavily, may need rollback plan.
|
|
26
|
+
3. **High Risk**: Full regression, integration tests required.
|
|
@@ -340,3 +340,4 @@ Agent: web_search("TypeScript null check best practices") // NO
|
|
|
340
340
|
- `security-scanner` — for CVE and vulnerability research
|
|
341
341
|
- `prompt-engineering` — for crafting effective search queries
|
|
342
342
|
- `multi-agent` — for fanning out research to subagents
|
|
343
|
+
- `output-standards` — for standardized `<next_steps>` formatting
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Research Web — WrongStack (Compact)
|
|
2
|
+
|
|
3
|
+
Conducts current-data web research with discipline: when to search, how to cross-validate, how to inject findings.
|
|
4
|
+
|
|
5
|
+
## Rules
|
|
6
|
+
|
|
7
|
+
1. Verify before claiming — never state a version number from training data without a live check.
|
|
8
|
+
2. Two-source minimum: single-source is tentative, two agreeing is signal.
|
|
9
|
+
3. Inject, don't repeat — use context_manager add_note after research.
|
|
10
|
+
4. Respect the stop rule: 2-3 searches + 1-2 fetches per topic.
|
|
11
|
+
5. Match tool to task: web_search for discovery, web_fetch for detail.
|
|
12
|
+
|
|
13
|
+
## Workflow
|
|
14
|
+
|
|
15
|
+
1. Quick lookup (1-2 turns): search → fetch → inject
|
|
16
|
+
2. Deep investigation (3-4 turns): search → parallel fetches → cross-reference → inject
|
|
17
|
+
3. Landscape survey: delegate to subagents, one per topic
|
|
18
|
+
|
|
19
|
+
## Source quality
|
|
20
|
+
|
|
21
|
+
| Tier | Examples | Trust |
|
|
22
|
+
|------|----------|-------|
|
|
23
|
+
| **Primary** | Official docs, GitHub releases | Cite as fact |
|
|
24
|
+
| **Secondary** | Tech blogs, conference talks | Cite with "according to" |
|
|
25
|
+
| **Tertiary** | Stack Overflow, Reddit | Corroborate before citing |
|
package/skills/sdd/SKILL.md
CHANGED
|
@@ -131,4 +131,5 @@ Stage shown in real-time. Pause stops after current iteration completes.
|
|
|
131
131
|
|
|
132
132
|
- `refactor-planner` — when the spec reveals a multi-file refactor
|
|
133
133
|
- `bug-hunter` — when a bugfix spec needs a root cause analysis section
|
|
134
|
-
- `multi-agent` — for executing parallel task groups
|
|
134
|
+
- `multi-agent` — for executing parallel task groups
|
|
135
|
+
- `output-standards` — for standardized `<next_steps>` formatting
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Spec-Driven Development — WrongStack (Compact)
|
|
2
|
+
|
|
3
|
+
Guides the SDD workflow: spec creation, task decomposition, and execution tracking.
|
|
4
|
+
|
|
5
|
+
## Rules
|
|
6
|
+
|
|
7
|
+
1. Always start with a spec — document acceptance criteria before writing code.
|
|
8
|
+
2. Decompose specs into atomic, testable tasks with clear dependencies.
|
|
9
|
+
3. Track progress via structured task graph, not ad-hoc checklists.
|
|
10
|
+
4. Validate implementation against spec acceptance criteria before marking complete.
|
|
11
|
+
5. Update the spec when discovery changes the design.
|
|
12
|
+
|
|
13
|
+
## Workflow
|
|
14
|
+
|
|
15
|
+
1. **Spec**: Define acceptance criteria with given/when/then.
|
|
16
|
+
2. **Decompose**: Break into tasks, identify dependencies.
|
|
17
|
+
3. **Execute**: Implement one task at a time, validate against AC.
|
|
18
|
+
4. **Review**: Verify the implementation satisfies the spec.
|
|
19
|
+
5. **Close**: Mark task done, update spec if needed.
|
|
@@ -4,7 +4,7 @@ description: |
|
|
|
4
4
|
Use this skill when scanning code or configuration for security vulnerabilities
|
|
5
5
|
in WrongStack. Triggers: user says "security", "vulnerability", "CVE", "secret",
|
|
6
6
|
"injection", "XSS", "SQL injection", "audit security", "supply chain".
|
|
7
|
-
version: 1.
|
|
7
|
+
version: 1.2.0
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# Security Scanner — WrongStack
|
|
@@ -94,7 +94,7 @@ const query = "SELECT * FROM users WHERE id = " + userId;
|
|
|
94
94
|
|
|
95
95
|
```typescript
|
|
96
96
|
// ❌ CRITICAL — hardcoded AWS credentials
|
|
97
|
-
const awsKey = "
|
|
97
|
+
const awsKey = "[REDACTED:aws_access_key]";
|
|
98
98
|
|
|
99
99
|
// ❌ CRITICAL — private key committed
|
|
100
100
|
const pem = "-----BEGIN RSA PRIVATE KEY-----\nMIIE...";
|
|
@@ -155,10 +155,17 @@ element.textContent = userInput;
|
|
|
155
155
|
- [ ] Move secrets to environment variables, add to .gitignore
|
|
156
156
|
- [ ] Use parameterized queries in `src/db/` files
|
|
157
157
|
- [ ] Add rate limiting to `src/api/` routes
|
|
158
|
+
|
|
159
|
+
<next_steps>
|
|
160
|
+
1. [CRITICAL] `src/config.ts` — remove hardcoded API key, use env var
|
|
161
|
+
2. [HIGH] `src/auth/login.ts` — replace exec() with execFile()
|
|
162
|
+
3. [MEDIUM] `src/api/routes.ts` — add rate limiting middleware
|
|
163
|
+
</next_steps>
|
|
158
164
|
```
|
|
159
165
|
|
|
160
166
|
## Skills in scope
|
|
161
167
|
|
|
162
168
|
- `bug-hunter` — for general code quality bugs found during security scan
|
|
163
169
|
- `audit-log` — for dependency version audit trails
|
|
164
|
-
- `git-flow` — for committing security patches properly
|
|
170
|
+
- `git-flow` — for committing security patches properly
|
|
171
|
+
- `output-standards` — for standardized `<next_steps>` formatting
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Security Scanner — WrongStack (Compact)
|
|
2
|
+
|
|
3
|
+
Scans code, configs, and dependencies for security issues. Reports with severity and concrete remediation.
|
|
4
|
+
|
|
5
|
+
## Rules
|
|
6
|
+
|
|
7
|
+
1. Always provide remediation — "found X" without "do Y" is useless.
|
|
8
|
+
2. Don't scan `node_modules` — use `npm audit` for supply chain.
|
|
9
|
+
3. Don't flag test fixtures — mock credentials in tests are acceptable.
|
|
10
|
+
4. Always run dependency audit — supply chain is a real attack vector.
|
|
11
|
+
5. Flag config issues (TLS disabled, HTTP in production) as CRITICAL.
|
|
12
|
+
|
|
13
|
+
## Critical patterns
|
|
14
|
+
|
|
15
|
+
| Pattern | Severity |
|
|
16
|
+
|---------|----------|
|
|
17
|
+
| Hardcoded GitHub token `ghp_[a-zA-Z0-9]{36}` | CRITICAL |
|
|
18
|
+
| Hardcoded AWS key `[A-Z0-9]{20}` | CRITICAL |
|
|
19
|
+
| Private key PEM `-----BEGIN.*PRIVATE KEY-----` | CRITICAL |
|
|
20
|
+
| `innerHTML = x` — use `textContent` | HIGH |
|
|
21
|
+
| `exec(\`cmd ${input}\`)` — use `execFile` with args | HIGH |
|
|
22
|
+
| SQL concatenation — use parameterized queries | CRITICAL |
|
|
23
|
+
| JWT in code `eyJ[a-zA-Z0-9_-]+` | HIGH |
|
|
@@ -125,4 +125,5 @@ Before writing the file, verify:
|
|
|
125
125
|
## Skills in scope
|
|
126
126
|
|
|
127
127
|
- `prompt-engineering` — for crafting the skill description and prompt text
|
|
128
|
-
- `git-flow` — for committing the new skill file
|
|
128
|
+
- `git-flow` — for committing the new skill file
|
|
129
|
+
- `output-standards` — for standardized `<next_steps>` formatting
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Skill Creator — WrongStack (Compact)
|
|
2
|
+
|
|
3
|
+
Guides the creation of new WrongStack skills. A skill is a Markdown file with YAML frontmatter.
|
|
4
|
+
|
|
5
|
+
## Rules
|
|
6
|
+
|
|
7
|
+
1. First sentence of `description` = trigger — the only thing the skill loader matches on.
|
|
8
|
+
2. Name must be kebab-case: `my-skill`, `docker-deploy` — lowercase, hyphens only.
|
|
9
|
+
3. Skills live in `.wrongstack/skills/<name>/SKILL.md` (project level) or `packages/core/skills/<name>/SKILL.md` (bundled).
|
|
10
|
+
4. After the trigger sentence, add `Triggers: user says "X", "Y", "Z".`
|
|
11
|
+
5. Content must be actionable — rules, patterns, anti-patterns.
|
|
12
|
+
6. End with "Skills in scope" listing related skills for delegation.
|
|
13
|
+
|
|
14
|
+
## Workflow
|
|
15
|
+
|
|
16
|
+
1. Ask the name — suggest kebab-case, validate format
|
|
17
|
+
2. Ask the trigger — "What situation should activate this skill?"
|
|
18
|
+
3. Ask the coverage — what rules, patterns, workflows?
|
|
19
|
+
4. Generate the SKILL.md — write to `.wrongstack/skills/<name>/SKILL.md`
|
|
20
|
+
5. Confirm — show the path
|
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tech-stack
|
|
3
3
|
description: |
|
|
4
|
-
Use this skill when
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
choices, and intervenes when the LLM hallucinates version numbers or
|
|
9
|
-
suggests 5+ year-old technology.
|
|
10
|
-
Triggers: user says "install", "package", "dependency", "upgrade",
|
|
11
|
-
"latest version", "add package", "pip install", "cargo add", "go get",
|
|
12
|
-
"gem install", "composer require", "nuget", "what version",
|
|
13
|
-
"which library", "tech stack", "choose framework".
|
|
14
|
-
version: 2.0.0
|
|
4
|
+
Use this skill when validating package versions, checking for outdated dependencies,
|
|
5
|
+
or evaluating third-party libraries in WrongStack. Triggers: user says "dependency",
|
|
6
|
+
"package version", "outdated", "npm audit", "deprecated package", "tech stack".
|
|
7
|
+
version: 1.2.0
|
|
15
8
|
---
|
|
16
9
|
|
|
17
10
|
# Tech Stack Validator — WrongStack (Language-Agnostic)
|
|
@@ -61,9 +54,8 @@ ecosystem. Runs as a single-shot delegate — fast, read-only, fire-and-forget.
|
|
|
61
54
|
- NuGet: deprecated flag, `listed: false`
|
|
62
55
|
|
|
63
56
|
5. **Reject prehistoric technology.** Any package/library/pattern that was
|
|
64
|
-
superseded ≥5 years ago is automatically rejected. Use the per-ecosystem
|
|
65
|
-
|
|
66
|
-
to web search: `"is <package> deprecated <ecosystem> <current_year>"`.
|
|
57
|
+
superseded ≥5 years ago is automatically rejected. Use the per-ecosystem built-in
|
|
58
|
+
preference map below before greenlighting any third-party dependency.
|
|
67
59
|
|
|
68
60
|
6. **Prefer built-in over third-party.** Every modern language runtime ships
|
|
69
61
|
standard library that obsoletes packages. Check the per-ecosystem built-in
|
|
@@ -73,77 +65,6 @@ ecosystem. Runs as a single-shot delegate — fast, read-only, fire-and-forget.
|
|
|
73
65
|
complete in 1–2 iterations. Detect → search registry → verify → report.
|
|
74
66
|
Do not recursively analyze transitive dependencies.
|
|
75
67
|
|
|
76
|
-
## Patterns
|
|
77
|
-
|
|
78
|
-
### Do
|
|
79
|
-
|
|
80
|
-
```
|
|
81
|
-
User: "Add requests to the project"
|
|
82
|
-
Agent: [detects pyproject.toml → Python ecosystem]
|
|
83
|
-
✅ requests 2.32.4 (latest stable as of 2026-06)
|
|
84
|
-
Verified via PyPI. requests is the de-facto HTTP library for Python.
|
|
85
|
-
**Install**: `pip install requests>=2.32`
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
```
|
|
89
|
-
User: "Cargo add serde"
|
|
90
|
-
Agent: [detects Cargo.toml → Rust ecosystem]
|
|
91
|
-
✅ serde 1.0.217 (latest stable)
|
|
92
|
-
Verified via crates.io. serde is the standard serialization framework for Rust.
|
|
93
|
-
**Install**: `cargo add serde@1`
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
```
|
|
97
|
-
User: "Add urllib2 for HTTP calls in our Python project"
|
|
98
|
-
Agent: ❌ REJECTED
|
|
99
|
-
"This isn't code, this is 16-year-old technology."
|
|
100
|
-
urllib2 was part of Python 2.x (released 2000). Python 3 unified everything
|
|
101
|
-
into `urllib.request` (stdlib) and `requests` (third-party, the community
|
|
102
|
-
standard). No package needed — or use `requests` for a better API.
|
|
103
|
-
→ Use: `import requests` or `from urllib.request import urlopen`
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
```
|
|
107
|
-
User: "Add axios for API calls"
|
|
108
|
-
Agent: ❌ REJECTED
|
|
109
|
-
"This isn't code, this is 12-year-old technology."
|
|
110
|
-
axios was released in 2014. Node.js 18+ (2022) includes native fetch with
|
|
111
|
-
AbortSignal.timeout(), streaming, and FormData. No package needed.
|
|
112
|
-
→ Use: `const res = await fetch(url, { signal: AbortSignal.timeout(5000) })`
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
### Don't
|
|
116
|
-
|
|
117
|
-
```
|
|
118
|
-
❌ Trusting the LLM's stale training data
|
|
119
|
-
Agent: "Use React 18.3.1 — it's the latest stable."
|
|
120
|
-
→ WRONG. React 19 has been stable since Dec 2024. Always check the registry.
|
|
121
|
-
|
|
122
|
-
❌ Assuming npm for everything
|
|
123
|
-
Agent: "pnpm add django" — Django is a Python package. Ecosystem detection
|
|
124
|
-
must happen before any install command is suggested.
|
|
125
|
-
|
|
126
|
-
❌ Accepting a package that doesn't exist
|
|
127
|
-
Agent: "Install @anthropic/sdk version 2.0.0" — verify against the correct registry first.
|
|
128
|
-
|
|
129
|
-
❌ Suggesting moment.js without challenge
|
|
130
|
-
Agent: "Use moment for date formatting" — moment is legacy. Suggest date-fns or Temporal.
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
## Workflow
|
|
134
|
-
|
|
135
|
-
```
|
|
136
|
-
0. DETECT — What ecosystem is this? (explicit hint → project files → ask)
|
|
137
|
-
1. LOOKUP — Find registry adapter for the ecosystem (see map below)
|
|
138
|
-
2. VERIFY — Fetch {registry.host}{registry.path/{pkg}} → extract {registry.field}
|
|
139
|
-
3. AUDIT — Age check (>2 years no release?), prehistoric check (in reject list?),
|
|
140
|
-
built-in check (stdlib alternative?), dead signals (deprecated/yanked?)
|
|
141
|
-
4. REPORT — APPROVED (with latest version + install command)
|
|
142
|
-
or REJECTED (with replacement + migration step + evidence)
|
|
143
|
-
Use the exact phrase "This isn't code, this is X-year-old technology"
|
|
144
|
-
when rejecting on age/prehistoric grounds.
|
|
145
|
-
```
|
|
146
|
-
|
|
147
68
|
## Ecosystem Registry Map
|
|
148
69
|
|
|
149
70
|
The central dispatch table. When verifying a package, use the adapter for the
|
|
@@ -161,147 +82,7 @@ detected ecosystem:
|
|
|
161
82
|
| `elixir` | Elixir | `hex.pm` | `/api/packages/{pkg}` | `releases[0].version` | mix | `{:pkg, "~> {major}.{minor}"}` (add to mix.exs) |
|
|
162
83
|
| `jvm` | Java/JVM | `search.maven.org` | `/solrsearch/select?q=g:{group}+AND+a:{artifact}&rows=1&wt=json` | `response.docs[0].latestVersion` | maven/gradle | `implementation '{group}:{artifact}:{version}'` |
|
|
163
84
|
|
|
164
|
-
|
|
165
|
-
Maven), fetch the endpoint, parse the JSON, then navigate to the version field
|
|
166
|
-
as specified. If the API shape has changed, fall back to web search.
|
|
167
|
-
|
|
168
|
-
**For ecosystems NOT in this table**, detect the language, then web-search
|
|
169
|
-
`"<language> package registry API latest version"` to discover the endpoint.
|
|
170
|
-
|
|
171
|
-
### Version checking — fallback chain
|
|
172
|
-
|
|
173
|
-
When the registry adapter is insufficient, try in this order:
|
|
174
|
-
1. **Registry API** (primary): fetch per the Ecosystem Registry Map above
|
|
175
|
-
2. **GitHub releases**: `fetch('https://api.github.com/repos/<owner>/<repo>/releases/latest')`
|
|
176
|
-
3. **Web search**: `"<package> latest version <ecosystem> <current_year>"`
|
|
177
|
-
4. **Project homepage**: fetch the package's documented "Install" page
|
|
178
|
-
|
|
179
|
-
## Per-Ecosystem Reject Lists
|
|
180
|
-
|
|
181
|
-
### JavaScript / TypeScript
|
|
182
|
-
|
|
183
|
-
| Prehistoric | Age | Replacement |
|
|
184
|
-
|-------------|-----|-------------|
|
|
185
|
-
| `axios`, `node-fetch`, `got`, `request` | 10-13yr | native `fetch` (Node 18+, 2022) |
|
|
186
|
-
| `moment` | 14yr | `date-fns`, `luxon`, or `Temporal` |
|
|
187
|
-
| `left-pad` | 10yr | native `String.prototype.padStart` |
|
|
188
|
-
| `crypto-js` | 12yr | native `Web Crypto` / `node:crypto` |
|
|
189
|
-
| `jQuery` (new projects) | 18yr | vanilla DOM / React / Vue / Svelte |
|
|
190
|
-
| `Backbone`, `Ember` | 14-15yr | React / Vue / Svelte |
|
|
191
|
-
| `Gulp`, `Grunt` | 12-13yr | `tsup`, `esbuild`, `vite` |
|
|
192
|
-
| `Bower` | 13yr | npm / pnpm |
|
|
193
|
-
| `CoffeeScript` | 16yr | TypeScript |
|
|
194
|
-
| `Flow` | 10yr | TypeScript |
|
|
195
|
-
| `Bluebird` | 12yr | native Promises |
|
|
196
|
-
| `underscore` | 16yr | `lodash` or native ES2020+ |
|
|
197
|
-
| `classnames` | 10yr | `clsx` or native `classList` |
|
|
198
|
-
|
|
199
|
-
### Python
|
|
200
|
-
|
|
201
|
-
| Prehistoric | Age | Replacement |
|
|
202
|
-
|-------------|-----|-------------|
|
|
203
|
-
| `urllib2`, `httplib` | 20+yr | `requests` or `httpx` |
|
|
204
|
-
| `distutils`, `setup.py` (new projects) | 20+yr | `pyproject.toml` + `hatch`/`poetry`/`setuptools` |
|
|
205
|
-
| `os.path` for path manipulation | — | `pathlib` (stdlib since 3.4) |
|
|
206
|
-
| `mock` (third-party) | 12yr | `unittest.mock` (stdlib since 3.3) |
|
|
207
|
-
| `pathlib2` | 8yr | `pathlib` (stdlib since 3.4) |
|
|
208
|
-
| `python-dateutil` (basic usage) | — | `datetime` + `zoneinfo` (stdlib 3.9+) |
|
|
209
|
-
| `typing` (backport) | — | stdlib `typing` (3.5+) |
|
|
210
|
-
| `2to3` tooling | 16yr | Python 3 is the only supported version |
|
|
211
|
-
| `futures` (backport) | — | `concurrent.futures` (stdlib 3.2+) |
|
|
212
|
-
|
|
213
|
-
### Rust
|
|
214
|
-
|
|
215
|
-
| Prehistoric | Age | Replacement |
|
|
216
|
-
|-------------|-----|-------------|
|
|
217
|
-
| `lazy_static` | 8yr | `std::sync::LazyLock` (1.80+, 2024) or `once_cell` |
|
|
218
|
-
| `try!` macro | 10yr | `?` operator (1.13+, 2016) |
|
|
219
|
-
| `error-chain` | 8yr | `thiserror` + `anyhow` |
|
|
220
|
-
| `rustc-serialize` | 10yr | `serde` |
|
|
221
|
-
|
|
222
|
-
### Go
|
|
223
|
-
|
|
224
|
-
| Prehistoric | Age | Replacement |
|
|
225
|
-
|-------------|-----|-------------|
|
|
226
|
-
| `dep` (tool) | 8yr | Go modules (`go mod`, 1.11+, 2018) |
|
|
227
|
-
| `ioutil` (stdlib, deprecated) | — | `io` + `os` packages (1.16+, 2021) |
|
|
228
|
-
| `gopath` dependency management | 10+yr | Go modules |
|
|
229
|
-
| `gopkg.in/yaml.v2` (for new code) | — | `gopkg.in/yaml.v3` or `encoding/json` |
|
|
230
|
-
| `glide`, `godep` | 9-10yr | Go modules |
|
|
231
|
-
|
|
232
|
-
### Ruby
|
|
233
|
-
|
|
234
|
-
| Prehistoric | Age | Replacement |
|
|
235
|
-
|-------------|-----|-------------|
|
|
236
|
-
| `therubyracer` | 12yr | `mini_racer` or Node.js-based execjs |
|
|
237
|
-
| `json` gem (explicit) | — | stdlib `json` (bundled since 2.3) |
|
|
238
|
-
| `rails` < 6.x (new projects) | 7+yr | Rails 7.x / 8.x |
|
|
239
|
-
| `protected_attributes` | 10yr | `strong_parameters` (Rails 4+) |
|
|
240
|
-
|
|
241
|
-
### .NET
|
|
242
|
-
|
|
243
|
-
| Prehistoric | Age | Replacement |
|
|
244
|
-
|-------------|-----|-------------|
|
|
245
|
-
| `System.Web` / WebForms | 20+yr | ASP.NET Core |
|
|
246
|
-
| `Windows Forms` (new projects) | 20+yr | WPF / MAUI / Avalonia |
|
|
247
|
-
| ` packages.config ` | 10+yr | `PackageReference` in csproj |
|
|
248
|
-
| `Newtonsoft.Json` (for new System.Text.Json-capable projects) | — | `System.Text.Json` (.NET Core 3+) |
|
|
249
|
-
|
|
250
|
-
### PHP
|
|
251
|
-
|
|
252
|
-
| Prehistoric | Age | Replacement |
|
|
253
|
-
|-------------|-----|-------------|
|
|
254
|
-
| `mysql_*` functions | 13yr | PDO or mysqli |
|
|
255
|
-
| `mcrypt` | 10yr | `openssl` / `sodium` (PHP 7.2+) |
|
|
256
|
-
| `PEAR` | 15+yr | Composer |
|
|
257
|
-
| `PHPUnit` < 9.x | — | PHPUnit 10.x / 11.x |
|
|
258
|
-
|
|
259
|
-
## Built-In Preference Map
|
|
260
|
-
|
|
261
|
-
Before approving any third-party package, check if the language's standard
|
|
262
|
-
library already solves this. These are the most common cases where a package
|
|
263
|
-
is unnecessary:
|
|
264
|
-
|
|
265
|
-
### JavaScript / TypeScript (Node 22+)
|
|
266
|
-
- `node:test` over `jest`/`mocha` (new projects)
|
|
267
|
-
- `node:sqlite` over `better-sqlite3` (Node 22.5+)
|
|
268
|
-
- `fetch`, `WebSocket`, `Web Crypto`, `AbortController`, `EventTarget` — all native
|
|
269
|
-
- `node:fs/promises` over `fs-extra`
|
|
270
|
-
- `URL` / `URLSearchParams` over `qs` / `query-string`
|
|
271
|
-
|
|
272
|
-
### Python (3.12+)
|
|
273
|
-
- `pathlib` over `os.path` / `glob`
|
|
274
|
-
- `unittest` + `pytest` (pytest *is* still preferred, but unittest exists)
|
|
275
|
-
- `dataclasses` over `attrs` (simple cases)
|
|
276
|
-
- `tomllib` over `toml` (3.11+)
|
|
277
|
-
- `zoneinfo` over `pytz` (3.9+)
|
|
278
|
-
- `graphlib` over custom topological sort (3.9+)
|
|
279
|
-
- `importlib.resources` over `pkg_resources`
|
|
280
|
-
|
|
281
|
-
### Rust (stable)
|
|
282
|
-
- `std::sync::LazyLock` over `lazy_static` / `once_cell` (1.80+)
|
|
283
|
-
- `std::sync::OnceLock` over `once_cell::sync::OnceCell`
|
|
284
|
-
- `std::cell::OnceCell` over `once_cell::unsync::OnceCell`
|
|
285
|
-
- `std::net` over `reqwest` (simple HTTP client cases)
|
|
286
|
-
|
|
287
|
-
### Go (1.22+)
|
|
288
|
-
- `net/http` over third-party HTTP routers (for simple APIs)
|
|
289
|
-
- `log/slog` over `logrus` / `zap` (1.21+)
|
|
290
|
-
- `slices` / `maps` packages over `golang.org/x/exp` backports (1.21+)
|
|
291
|
-
- `cmp` / `math/rand/v2` / `unique` — all stdlib additions
|
|
292
|
-
|
|
293
|
-
## Dead Package Criteria
|
|
294
|
-
|
|
295
|
-
| Signal | Threshold | Action |
|
|
296
|
-
|--------|-----------|--------|
|
|
297
|
-
| No release | >2 years | Flag + check for replacement |
|
|
298
|
-
| No release + critical CVEs | >1 year | REJECT automatically |
|
|
299
|
-
| Deprecated/yanked on registry | Any | REJECT + suggest replacement |
|
|
300
|
-
| Repository archived | Any | REJECT + suggest replacement |
|
|
301
|
-
| Low adoption | <500 weekly downloads (npm) / <100 stars + no recent commits | WARN + suggest alternative |
|
|
302
|
-
| Last commit | >3 years ago, no response to issues | WARN + flag as unmaintained |
|
|
303
|
-
|
|
304
|
-
## Output Format
|
|
85
|
+
## Output format
|
|
305
86
|
|
|
306
87
|
```
|
|
307
88
|
### Tech Stack Validation — <package>
|
|
@@ -322,6 +103,11 @@ When REJECTED:
|
|
|
322
103
|
When APPROVED:
|
|
323
104
|
**Install**: `<ecosystem install command>`
|
|
324
105
|
**Note**: <any caveats about the version, semver range, or compatibility>
|
|
106
|
+
|
|
107
|
+
<next_steps>
|
|
108
|
+
1. [APPROVED/REJECTED] Package decision with rationale
|
|
109
|
+
2. [If rejected] Migration step to the recommended alternative
|
|
110
|
+
</next_steps>
|
|
325
111
|
```
|
|
326
112
|
|
|
327
113
|
## Skills in scope
|
|
@@ -331,3 +117,4 @@ When APPROVED:
|
|
|
331
117
|
- `typescript-strict` — for TypeScript version alignment
|
|
332
118
|
- `security-scanner` — for packages with known CVEs
|
|
333
119
|
- `docker-deploy` — for base image version pinning
|
|
120
|
+
- `output-standards` — for standardized `<next_steps>` formatting
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Tech Stack Validator — WrongStack (Compact)
|
|
2
|
+
|
|
3
|
+
Validates package/library/framework choices before they are committed.
|
|
4
|
+
|
|
5
|
+
## Rules
|
|
6
|
+
|
|
7
|
+
1. Detect the ecosystem first (package.json → JS, pyproject.toml → Python, Cargo.toml → Rust, etc.).
|
|
8
|
+
2. Verify existence — consult the ecosystem's registry endpoint.
|
|
9
|
+
3. Check the latest version from the registry (never trust training data versions).
|
|
10
|
+
4. Reject dead packages — no release in >2 years + unresolved critical issues.
|
|
11
|
+
5. Reject prehistoric technology — superseded ≥5 years ago.
|
|
12
|
+
6. Prefer built-in over third-party — many modern runtimes obsolete packages.
|
|
13
|
+
7. Single-shot budget: detect → search registry → verify → report.
|
|
14
|
+
|
|
15
|
+
## Ecosystem registry map
|
|
16
|
+
|
|
17
|
+
| Language | Registry | Package Manager |
|
|
18
|
+
|----------|----------|-----------------|
|
|
19
|
+
| JavaScript/TS | registry.npmjs.org | pnpm/npm/yarn |
|
|
20
|
+
| Python | pypi.org | pip/poetry |
|
|
21
|
+
| Rust | crates.io | cargo |
|
|
22
|
+
| Go | proxy.golang.org | go |
|
|
23
|
+
| Ruby | rubygems.org | bundler |
|
|
24
|
+
| .NET | api.nuget.org | dotnet |
|
|
25
|
+
| PHP | repo.packagist.org | composer |
|
package/skills/testing/SKILL.md
CHANGED
|
@@ -168,3 +168,4 @@ coverageThreshold: {
|
|
|
168
168
|
- `typescript-strict` — for type-safe test assertions
|
|
169
169
|
- `node-modern` — for async/test patterns with AbortSignal
|
|
170
170
|
- `git-flow` — for committing tests with the code they test
|
|
171
|
+
- `output-standards` — for standardized `<next_steps>` formatting
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Testing — WrongStack (Compact)
|
|
2
|
+
|
|
3
|
+
Writes and reviews tests for WrongStack TypeScript code (vitest, pnpm workspaces).
|
|
4
|
+
|
|
5
|
+
## Rules
|
|
6
|
+
|
|
7
|
+
1. Co-locate tests: `src/foo.ts` → `tests/foo.test.ts` (same package).
|
|
8
|
+
2. Always test public API surfaces — don't test internals.
|
|
9
|
+
3. Use `vi.mock()` for external deps; never mock internal modules.
|
|
10
|
+
4. Every async test needs a timeout: `test(..., { timeout: 5000 })`.
|
|
11
|
+
5. Mock time with `vi.useFakeTimers()` for debounce/throttle tests.
|
|
12
|
+
6. Coverage gate: new code must have ≥70% coverage.
|
|
13
|
+
7. Don't commit test-only deps — test deps go in `devDependencies`.
|
|
14
|
+
8. Tests must be isolated — each test cleans up its mocks/state.
|
|
15
|
+
|
|
16
|
+
## Key patterns
|
|
17
|
+
|
|
18
|
+
- **Unit**: Pure logic, parsing, transformations.
|
|
19
|
+
- **Integration**: API calls, file I/O, tool chains.
|
|
20
|
+
- **E2E**: Full command flow, CLI smoke tests.
|
|
21
|
+
- Mock `node:fs/promises` with `vi.mock()`, use `vi.mocked(fs.readFile).mockResolvedValue()`.
|
|
22
|
+
- Use `afterEach(() => { vi.restoreAllMocks(); })` for isolation.
|
|
@@ -236,4 +236,5 @@ console.log(name!.toUpperCase());
|
|
|
236
236
|
|
|
237
237
|
- `node-modern` — for TypeScript + ESM patterns
|
|
238
238
|
- `react-modern` — for React + TypeScript patterns
|
|
239
|
-
- `bug-hunter` — for type-related bugs like unsafe casts
|
|
239
|
+
- `bug-hunter` — for type-related bugs like unsafe casts
|
|
240
|
+
- `output-standards` — for standardized `<next_steps>` formatting
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# TypeScript Strict Mode — WrongStack (Compact)
|
|
2
|
+
|
|
3
|
+
Strict TypeScript patterns for WrongStack: exhaustive switch, branded types, discriminated unions, and `noUncheckedIndexedAccess`.
|
|
4
|
+
|
|
5
|
+
## Rules
|
|
6
|
+
|
|
7
|
+
1. Never silence errors with `as any` — use `as unknown as T` only at trust boundaries with a comment.
|
|
8
|
+
2. Don't use `!` non-null assertion — silence the type checker without explanation.
|
|
9
|
+
3. Always annotate return types on exported functions.
|
|
10
|
+
4. Use `Promise<unknown>` or generics instead of `Promise<any>`.
|
|
11
|
+
5. Be specific with types — `Function` and `Object` are too broad.
|
|
12
|
+
6. Enable `noUncheckedIndexedAccess` — always handle the `undefined` case.
|
|
13
|
+
|
|
14
|
+
## Key patterns
|
|
15
|
+
|
|
16
|
+
- **Exhaustive switch**: Create `assertNever(x: never)` and use it in the `default` branch of every switch on a union.
|
|
17
|
+
- **Branded types**: `type UserId = string & { readonly __brand: 'UserId' }` for invariant string types.
|
|
18
|
+
- **Discriminated unions**: Prefer `{ status: 'success'; data: T } | { status: 'error'; error: E }` over optional fields.
|
|
19
|
+
- **noUncheckedIndexedAccess**: Use `items.at(0)` or `if (items[0] !== undefined)` — never assume array access succeeds.
|