@mrciphersmith/keryx 0.2.164 → 0.3.1
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/README.md +4 -1
- package/dist/cli.js +82540 -50300
- package/dist/core.js +28967 -18937
- package/package.json +2 -2
- package/src/gdgraph/affected-report.ts +141 -0
- package/src/gdgraph/build.ts +170 -23
- package/src/gdgraph/service.ts +6 -0
- package/src/gdgraph/staleness.ts +253 -45
- package/src/gdskills/bundled/agents/codebase-navigator.md +55 -0
- package/src/gdskills/bundled/agents/design-advisor.md +64 -0
- package/src/gdskills/bundled/agents/docs-maintainer.md +56 -0
- package/src/gdskills/bundled/agents/end-to-end-tester.md +56 -0
- package/src/gdskills/bundled/agents/error-path-auditor.md +57 -0
- package/src/gdskills/bundled/agents/go-build-fixer.md +52 -0
- package/src/gdskills/bundled/agents/go-code-auditor.md +49 -0
- package/src/gdskills/bundled/agents/performance-auditor.md +63 -0
- package/src/gdskills/bundled/agents/python-build-fixer.md +52 -0
- package/src/gdskills/bundled/agents/python-code-auditor.md +49 -0
- package/src/gdskills/bundled/agents/refactoring-steward.md +61 -0
- package/src/gdskills/bundled/agents/security-auditor.md +62 -0
- package/src/gdskills/bundled/agents/test-first-driver.md +61 -0
- package/src/gdskills/bundled/agents/work-planner.md +62 -0
- package/src/gdskills/bundled/install-manifest.json +797 -0
- package/src/gdskills/bundled/rules/core/model-selection.mdc +51 -0
- package/src/gdskills/bundled/rules/core/skill-lifecycle.mdc +29 -1
- package/src/gdskills/bundled/rules/core/skills-storage-workflow.mdc +2 -2
- package/src/gdskills/bundled/skills/review/code-style-review/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-jev-rules/SKILL.md +267 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.detail.md +26 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.md +75 -247
- package/src/gdskills/bundled/skills/review/review-orchestrator/output-contract.schema.json +19 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/reviewer-finding.schema.json +10 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/reviewer-input.schema.json +5 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/templates/pr-comment-backend.md +50 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/templates/pr-comment-frontend.md +52 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/templates/review-report.md +143 -0
- package/src/gdskills/bundled/stacks/angular/agent-refs.json +4 -0
- package/src/gdskills/bundled/stacks/angular/governance/eval.json +1751 -0
- package/src/gdskills/bundled/stacks/angular/governance/scout.json +32 -0
- package/src/gdskills/bundled/stacks/angular/pack.json +55 -0
- package/src/gdskills/bundled/stacks/angular/rules/coding-style.mdc +82 -0
- package/src/gdskills/bundled/stacks/angular/rules/patterns.mdc +84 -0
- package/src/gdskills/bundled/stacks/angular/rules/security.mdc +70 -0
- package/src/gdskills/bundled/stacks/angular/rules/testing.mdc +73 -0
- package/src/gdskills/bundled/stacks/angular/skills/angular-build-fix/SKILL.md +127 -0
- package/src/gdskills/bundled/stacks/angular/skills/angular-build-fix/evals.json +72 -0
- package/src/gdskills/bundled/stacks/angular/skills/angular-code-review/SKILL.md +98 -0
- package/src/gdskills/bundled/stacks/angular/skills/angular-code-review/evals.json +73 -0
- package/src/gdskills/bundled/stacks/angular/skills/angular-implementation/SKILL.md +112 -0
- package/src/gdskills/bundled/stacks/angular/skills/angular-implementation/evals.json +74 -0
- package/src/gdskills/bundled/stacks/angular/skills/angular-testing/SKILL.md +102 -0
- package/src/gdskills/bundled/stacks/angular/skills/angular-testing/evals.json +71 -0
- package/src/gdskills/bundled/stacks/go/agent-refs.json +3 -0
- package/src/gdskills/bundled/stacks/go/governance/eval.json +1745 -0
- package/src/gdskills/bundled/stacks/go/governance/scout.json +31 -0
- package/src/gdskills/bundled/stacks/go/pack.json +41 -0
- package/src/gdskills/bundled/stacks/go/rules/coding-style.mdc +85 -0
- package/src/gdskills/bundled/stacks/go/rules/patterns.mdc +65 -0
- package/src/gdskills/bundled/stacks/go/rules/security.mdc +73 -0
- package/src/gdskills/bundled/stacks/go/rules/testing.mdc +68 -0
- package/src/gdskills/bundled/stacks/go/skills/go-build-fix/SKILL.md +138 -0
- package/src/gdskills/bundled/stacks/go/skills/go-build-fix/evals.json +75 -0
- package/src/gdskills/bundled/stacks/go/skills/go-code-review/SKILL.md +121 -0
- package/src/gdskills/bundled/stacks/go/skills/go-code-review/evals.json +72 -0
- package/src/gdskills/bundled/stacks/go/skills/go-implementation/SKILL.md +122 -0
- package/src/gdskills/bundled/stacks/go/skills/go-implementation/evals.json +76 -0
- package/src/gdskills/bundled/stacks/go/skills/go-testing/SKILL.md +126 -0
- package/src/gdskills/bundled/stacks/go/skills/go-testing/evals.json +73 -0
- package/src/gdskills/bundled/stacks/mobx/agent-refs.json +4 -0
- package/src/gdskills/bundled/stacks/mobx/governance/eval.json +904 -0
- package/src/gdskills/bundled/stacks/mobx/governance/scout.json +18 -0
- package/src/gdskills/bundled/stacks/mobx/pack.json +28 -0
- package/src/gdskills/bundled/stacks/mobx/rules/coding-style.mdc +91 -0
- package/src/gdskills/bundled/stacks/mobx/rules/patterns.mdc +122 -0
- package/src/gdskills/bundled/stacks/mobx/rules/security.mdc +56 -0
- package/src/gdskills/bundled/stacks/mobx/rules/testing.mdc +63 -0
- package/src/gdskills/bundled/stacks/mobx/skills/mobx-observable-testing/SKILL.md +124 -0
- package/src/gdskills/bundled/stacks/mobx/skills/mobx-observable-testing/evals.json +73 -0
- package/src/gdskills/bundled/stacks/mobx/skills/mobx-store-implementation/SKILL.md +149 -0
- package/src/gdskills/bundled/stacks/mobx/skills/mobx-store-implementation/evals.json +74 -0
- package/src/gdskills/bundled/stacks/nestjs/agent-refs.json +4 -0
- package/src/gdskills/bundled/stacks/nestjs/governance/eval.json +1308 -0
- package/src/gdskills/bundled/stacks/nestjs/governance/scout.json +34 -0
- package/src/gdskills/bundled/stacks/nestjs/pack.json +53 -0
- package/src/gdskills/bundled/stacks/nestjs/rules/coding-style.mdc +70 -0
- package/src/gdskills/bundled/stacks/nestjs/rules/patterns.mdc +83 -0
- package/src/gdskills/bundled/stacks/nestjs/rules/security.mdc +73 -0
- package/src/gdskills/bundled/stacks/nestjs/rules/testing.mdc +69 -0
- package/src/gdskills/bundled/stacks/nestjs/skills/nestjs-build-fix/SKILL.md +157 -0
- package/src/gdskills/bundled/stacks/nestjs/skills/nestjs-build-fix/evals.json +70 -0
- package/src/gdskills/bundled/stacks/nestjs/skills/nestjs-implementation/SKILL.md +129 -0
- package/src/gdskills/bundled/stacks/nestjs/skills/nestjs-implementation/evals.json +71 -0
- package/src/gdskills/bundled/stacks/nestjs/skills/nestjs-testing/SKILL.md +143 -0
- package/src/gdskills/bundled/stacks/nestjs/skills/nestjs-testing/evals.json +69 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/agent-refs.json +4 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/governance/eval.json +2413 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/governance/scout.json +42 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/pack.json +42 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/rules/coding-style.mdc +69 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/rules/patterns.mdc +88 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/rules/security.mdc +72 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/rules/testing.mdc +64 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/skills/nextjs-nuxt-build-fix/SKILL.md +147 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/skills/nextjs-nuxt-build-fix/evals.json +75 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/skills/nextjs-nuxt-code-review/SKILL.md +118 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/skills/nextjs-nuxt-code-review/evals.json +76 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/skills/nextjs-nuxt-implementation/SKILL.md +135 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/skills/nextjs-nuxt-implementation/evals.json +78 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/skills/nextjs-nuxt-testing/SKILL.md +116 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/skills/nextjs-nuxt-testing/evals.json +75 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/skills/nextjs-nuxt-upgrade-migration/SKILL.md +134 -0
- package/src/gdskills/bundled/stacks/nextjs-nuxt/skills/nextjs-nuxt-upgrade-migration/evals.json +76 -0
- package/src/gdskills/bundled/stacks/python/agent-refs.json +3 -0
- package/src/gdskills/bundled/stacks/python/governance/eval.json +1758 -0
- package/src/gdskills/bundled/stacks/python/governance/scout.json +34 -0
- package/src/gdskills/bundled/stacks/python/pack.json +41 -0
- package/src/gdskills/bundled/stacks/python/rules/coding-style.mdc +63 -0
- package/src/gdskills/bundled/stacks/python/rules/patterns.mdc +88 -0
- package/src/gdskills/bundled/stacks/python/rules/security.mdc +84 -0
- package/src/gdskills/bundled/stacks/python/rules/testing.mdc +77 -0
- package/src/gdskills/bundled/stacks/python/skills/python-build-fix/SKILL.md +144 -0
- package/src/gdskills/bundled/stacks/python/skills/python-build-fix/evals.json +74 -0
- package/src/gdskills/bundled/stacks/python/skills/python-code-review/SKILL.md +155 -0
- package/src/gdskills/bundled/stacks/python/skills/python-code-review/evals.json +72 -0
- package/src/gdskills/bundled/stacks/python/skills/python-implementation/SKILL.md +143 -0
- package/src/gdskills/bundled/stacks/python/skills/python-implementation/evals.json +78 -0
- package/src/gdskills/bundled/stacks/python/skills/python-testing/SKILL.md +132 -0
- package/src/gdskills/bundled/stacks/python/skills/python-testing/evals.json +73 -0
- package/src/gdskills/bundled/stacks/react/agent-refs.json +4 -0
- package/src/gdskills/bundled/stacks/react/governance/eval.json +2188 -0
- package/src/gdskills/bundled/stacks/react/governance/scout.json +40 -0
- package/src/gdskills/bundled/stacks/react/pack.json +42 -0
- package/src/gdskills/bundled/stacks/react/rules/coding-style.mdc +58 -0
- package/src/gdskills/bundled/stacks/react/rules/patterns.mdc +79 -0
- package/src/gdskills/bundled/stacks/react/rules/security.mdc +70 -0
- package/src/gdskills/bundled/stacks/react/rules/testing.mdc +60 -0
- package/src/gdskills/bundled/stacks/react/skills/react-build-fix/SKILL.md +139 -0
- package/src/gdskills/bundled/stacks/react/skills/react-build-fix/evals.json +72 -0
- package/src/gdskills/bundled/stacks/react/skills/react-code-review/SKILL.md +148 -0
- package/src/gdskills/bundled/stacks/react/skills/react-code-review/evals.json +74 -0
- package/src/gdskills/bundled/stacks/react/skills/react-implementation/SKILL.md +140 -0
- package/src/gdskills/bundled/stacks/react/skills/react-implementation/evals.json +74 -0
- package/src/gdskills/bundled/stacks/react/skills/react-testing/SKILL.md +142 -0
- package/src/gdskills/bundled/stacks/react/skills/react-testing/evals.json +83 -0
- package/src/gdskills/bundled/stacks/react/skills/react-upgrade-migration/SKILL.md +155 -0
- package/src/gdskills/bundled/stacks/react/skills/react-upgrade-migration/evals.json +74 -0
- package/src/gdskills/bundled/stacks/ts-js-node/agent-refs.json +4 -0
- package/src/gdskills/bundled/stacks/ts-js-node/governance/eval.json +2155 -0
- package/src/gdskills/bundled/stacks/ts-js-node/governance/scout.json +40 -0
- package/src/gdskills/bundled/stacks/ts-js-node/pack.json +41 -0
- package/src/gdskills/bundled/stacks/ts-js-node/rules/coding-style.mdc +73 -0
- package/src/gdskills/bundled/stacks/ts-js-node/rules/patterns.mdc +61 -0
- package/src/gdskills/bundled/stacks/ts-js-node/rules/security.mdc +71 -0
- package/src/gdskills/bundled/stacks/ts-js-node/rules/testing.mdc +63 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-build-fix/SKILL.md +137 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-build-fix/evals.json +73 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-code-review/SKILL.md +124 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-code-review/evals.json +74 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-esm-migration/SKILL.md +152 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-esm-migration/evals.json +71 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-implementation/SKILL.md +127 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-implementation/evals.json +72 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-testing/SKILL.md +134 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-testing/evals.json +70 -0
- package/src/gdskills/bundled/stacks/vue/agent-refs.json +4 -0
- package/src/gdskills/bundled/stacks/vue/governance/eval.json +2215 -0
- package/src/gdskills/bundled/stacks/vue/governance/scout.json +42 -0
- package/src/gdskills/bundled/stacks/vue/pack.json +42 -0
- package/src/gdskills/bundled/stacks/vue/rules/coding-style.mdc +73 -0
- package/src/gdskills/bundled/stacks/vue/rules/patterns.mdc +84 -0
- package/src/gdskills/bundled/stacks/vue/rules/security.mdc +60 -0
- package/src/gdskills/bundled/stacks/vue/rules/testing.mdc +69 -0
- package/src/gdskills/bundled/stacks/vue/skills/vue-build-fix/SKILL.md +137 -0
- package/src/gdskills/bundled/stacks/vue/skills/vue-build-fix/evals.json +72 -0
- package/src/gdskills/bundled/stacks/vue/skills/vue-code-review/SKILL.md +120 -0
- package/src/gdskills/bundled/stacks/vue/skills/vue-code-review/evals.json +71 -0
- package/src/gdskills/bundled/stacks/vue/skills/vue-implementation/SKILL.md +122 -0
- package/src/gdskills/bundled/stacks/vue/skills/vue-implementation/evals.json +72 -0
- package/src/gdskills/bundled/stacks/vue/skills/vue-testing/SKILL.md +115 -0
- package/src/gdskills/bundled/stacks/vue/skills/vue-testing/evals.json +72 -0
- package/src/gdskills/bundled/stacks/vue/skills/vue2-to-vue3-migration/SKILL.md +135 -0
- package/src/gdskills/bundled/stacks/vue/skills/vue2-to-vue3-migration/evals.json +71 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"query": "Use when resolving `tsc` type errors, module resolution failures (ESM/CJS, moduleResolution nodenext/bundler, `type: module`, exports maps), or lint/test failures blocking a Node.js TypeScript/JavaScript build. Applies the smallest root-cause fix and never silences the checker with @ts-ignore, any, or eslint-disable. Not for Go/Rust/Python build failures, and not for implementing new features (use nodejs-implementation).",
|
|
4
|
+
"decision": "create",
|
|
5
|
+
"topMatch": "ts-js-node/nodejs-implementation",
|
|
6
|
+
"recordedAt": "2026-09-24T15:57:58.995Z",
|
|
7
|
+
"skillName": "nodejs-build-fix"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"query": "Use when migrating a Node.js package or app from CommonJS to ES modules -- package.json type/exports map changes, adding file extensions to relative imports, replacing __dirname/__filename with import.meta.dirname/filename, fixing require() of an ESM-only dependency, dual-package hazards, and the resulting Jest/tsconfig adjustments. Not for a greenfield ESM project (use nodejs-implementation) or a general dependency upgrade (use dependency-update).",
|
|
11
|
+
"decision": "create",
|
|
12
|
+
"topMatch": "ts-js-node/nodejs-build-fix",
|
|
13
|
+
"recordedAt": "2026-09-24T15:58:09.568Z",
|
|
14
|
+
"skillName": "nodejs-esm-migration"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"query": "Use when implementing or extending a feature in a Node.js service, library, or CLI written in TypeScript or JavaScript -- covers tsconfig strictness, ESM/node: protocol imports, async/await with AbortSignal, error handling with cause, and input validation at process boundaries. Not for UI markup/rendering code (use the matching UI framework pack) or writing/fixing tests (use nodejs-testing).",
|
|
18
|
+
"decision": "fork",
|
|
19
|
+
"topMatch": "ts-js-node/nodejs-testing",
|
|
20
|
+
"recordedAt": "2026-09-24T15:58:09.708Z",
|
|
21
|
+
"skillName": "nodejs-implementation",
|
|
22
|
+
"justification": "Nearest matches: ts-js-node/nodejs-testing (0.40) writes/fixes the test suite for Node code, a different lifecycle stage than implementing the feature itself. ts-js-node/nodejs-build-fix (0.28) fixes tsc/module-resolution errors on an existing build, not new feature implementation. ts-js-node/nodejs-code-review (0.24) is read-only review that never edits code. None perform implementation work (writing feature code with tsconfig/ESM/AbortSignal/cause-chain/input-validation concerns), so this is a genuine fork by lifecycle stage, not a substitute."
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"query": "Use when a Node.js project's test suite (node:test, Vitest, Jest, or bun test) needs writing, extending, or fixing for TypeScript or JavaScript server/library/CLI code -- covers discovering the project's actual runner, mocking at process boundaries, fake timers, and deterministic async assertions. Not for pytest/Python tests, and not for auditing test conventions without changing test files (that is review-testing-practices).",
|
|
26
|
+
"decision": "fork",
|
|
27
|
+
"topMatch": "react/react-testing",
|
|
28
|
+
"recordedAt": "2026-09-24T15:58:09.847Z",
|
|
29
|
+
"skillName": "nodejs-testing",
|
|
30
|
+
"justification": "Nearest matches: react/react-testing (0.36) covers React Testing Library/JSX component tests, a different framework and rendering surface than Node server/library/CLI tests. ts-js-node/nodejs-implementation (0.35) implements feature code, not writing/fixing tests -- a different lifecycle stage. python/python-testing (0.32) is pytest-specific for Python, wrong language and runner ecosystem (node:test/Vitest/Jest/bun test). None substitute for discovering and using the Node project's actual test runner, so this is a genuine fork, not a substitute."
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"query": "Use when reviewing a TypeScript or JavaScript Node.js change (a diff on a server, library, or CLI) for floating promises, unhandled rejections, `any` leaks, event-loop-blocking sync calls, resource cleanup gaps, and dependency risk. Read-only -- judges the diff and reports findings, never edits or authors source. Not for React component review, general architecture review, or security-only audits (use review-security-code for a broader OWASP pass).",
|
|
34
|
+
"decision": "fork",
|
|
35
|
+
"topMatch": "python/python-code-review",
|
|
36
|
+
"recordedAt": "2026-09-24T15:58:16.450Z",
|
|
37
|
+
"skillName": "nodejs-code-review",
|
|
38
|
+
"justification": "Nearest matches: python/python-code-review (0.32) reviews Python-specific mutation/safety issues, wrong language -- no coverage of Node's event loop, floating promises, or dependency risk vocabulary. go/go-code-review (0.21) reviews Go concurrency/idiom risks (goroutines, context misuse), unrelated to Node's promise/event-loop concerns. ts-js-node/nodejs-testing (0.20) writes/fixes test files, not a read-only review of a diff. None cover Node/TS-specific floating-promise, unhandled-rejection, event-loop-blocking, or resource-cleanup review, so this is a genuine fork by language/runtime, not a substitute."
|
|
39
|
+
}
|
|
40
|
+
]
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "ts-js-node",
|
|
3
|
+
"family": "language",
|
|
4
|
+
"modules": ["ts-js-node-rules", "ts-js-node-skills"],
|
|
5
|
+
"detectionMarkers": ["typescript", "javascript", "node"],
|
|
6
|
+
"provenance": {
|
|
7
|
+
"origin": "authored",
|
|
8
|
+
"sourceRef": "flow 314, Wave 4 batch 1"
|
|
9
|
+
},
|
|
10
|
+
"stability": "experimental",
|
|
11
|
+
"skills": {
|
|
12
|
+
"implement": ["nodejs-implementation"],
|
|
13
|
+
"test": ["nodejs-testing"],
|
|
14
|
+
"review": ["nodejs-code-review"],
|
|
15
|
+
"build-fix": ["nodejs-build-fix"],
|
|
16
|
+
"migrate": ["nodejs-esm-migration"]
|
|
17
|
+
},
|
|
18
|
+
"agentProfile": {
|
|
19
|
+
"displayName": "TypeScript/JavaScript (Node.js)",
|
|
20
|
+
"auditFocus": [
|
|
21
|
+
"Every Promise is awaited, returned, or explicitly voided -- no floating promises",
|
|
22
|
+
"Async work has a rejection handler somewhere in its chain -- no unhandled rejections",
|
|
23
|
+
"No new `any` on a changed signature or a cast that erases a narrower type the code already had",
|
|
24
|
+
"No synchronous fs/crypto/zlib call on a request-handling or otherwise hot path",
|
|
25
|
+
"Opened resources (file handles, DB connections, timers, listeners, child processes) are closed or cleared on every exit path, including errors",
|
|
26
|
+
"A new runtime dependency is justified -- no unvetted package added for one small utility"
|
|
27
|
+
],
|
|
28
|
+
"buildCommands": [
|
|
29
|
+
"npm run build",
|
|
30
|
+
"npx tsc --noEmit",
|
|
31
|
+
"npx eslint .",
|
|
32
|
+
"npm test"
|
|
33
|
+
],
|
|
34
|
+
"fixGuardrails": [
|
|
35
|
+
"Never silence a `tsc` error with `@ts-ignore`, `@ts-expect-error` without a linked issue, or a cast to `any`",
|
|
36
|
+
"Never add an eslint-disable comment to make a lint failure go away instead of fixing the underlying code",
|
|
37
|
+
"Never flip `strict`/`noImplicitAny`/`skipLibCheck` or widen `moduleResolution` in tsconfig.json to make an error disappear",
|
|
38
|
+
"Never delete or skip a failing test to turn the suite green"
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
extends: common
|
|
3
|
+
paths: ["**/*.ts", "**/*.js", "**/*.mjs", "**/*.cjs"]
|
|
4
|
+
metadata:
|
|
5
|
+
origin: authored
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# TypeScript/JavaScript (Node.js) coding style
|
|
9
|
+
|
|
10
|
+
Narrows `core-common-rules`' stack-agnostic style rules to Node.js server,
|
|
11
|
+
library and CLI code written in TypeScript or JavaScript. Applies to
|
|
12
|
+
`*.ts`/`*.js`/`*.mjs`/`*.cjs` files; JSX/TSX component code belongs to the
|
|
13
|
+
`react` pack, which extends this one. Everything not Node/TS-specific still
|
|
14
|
+
comes from the common rules this file `extends`.
|
|
15
|
+
|
|
16
|
+
## Typing and module shape
|
|
17
|
+
|
|
18
|
+
- Keep `tsconfig.json`'s `strict: true` on; do not narrow it or add
|
|
19
|
+
per-file `// @ts-nocheck` to make new code compile.
|
|
20
|
+
- Prefer `unknown` over `any` for a value whose shape is not yet known;
|
|
21
|
+
narrow it with a type guard before use. An untyped external payload
|
|
22
|
+
(parsed JSON, a fetch body) is `unknown`, not `any`.
|
|
23
|
+
- Match `moduleResolution` to what the project already declares
|
|
24
|
+
(`nodenext` or `bundler`) -- do not mix `require()` and `import` in code
|
|
25
|
+
the project already runs as ESM (`"type": "module"` in `package.json`).
|
|
26
|
+
- Import Node built-ins with the `node:` prefix (`node:fs`, `node:path`,
|
|
27
|
+
`node:crypto`) -- some built-ins (`node:sea`, `node:sqlite`, `node:test`)
|
|
28
|
+
require it outright, and it disambiguates a built-in from a same-named
|
|
29
|
+
npm package everywhere else.
|
|
30
|
+
- Use `import type { X } from "..."` (or `verbatimModuleSyntax`, when the
|
|
31
|
+
project enables it) for type-only imports so they are erased from the
|
|
32
|
+
emitted JS.
|
|
33
|
+
|
|
34
|
+
## Naming and structure
|
|
35
|
+
|
|
36
|
+
- `camelCase` for functions/variables, `PascalCase` for classes/types/
|
|
37
|
+
interfaces/enums, `UPPER_SNAKE_CASE` for module-level constants that are
|
|
38
|
+
effectively compile-time -- the ecosystem baseline, not a house variant.
|
|
39
|
+
- One cohesive export group per module; a file mixing unrelated public
|
|
40
|
+
exports should split along the seam its imports already show.
|
|
41
|
+
- Prefer named exports over a single default export in a module with more
|
|
42
|
+
than one thing to export -- named exports survive a rename/refactor with
|
|
43
|
+
a traceable diff; a default export does not.
|
|
44
|
+
|
|
45
|
+
## Async and errors
|
|
46
|
+
|
|
47
|
+
- `async`/`await` over raw `.then()` chains for new code; a `.then()` chain
|
|
48
|
+
longer than one link should become `await` with a `try`/`catch`.
|
|
49
|
+
- Every `Promise` is awaited, returned to a caller that awaits it, or
|
|
50
|
+
explicitly discarded with `void somePromise()` when firing-and-forgetting
|
|
51
|
+
is genuinely intended -- never a bare unreferenced promise statement.
|
|
52
|
+
- Pass `AbortSignal` (`AbortSignal.timeout(ms)` or a caller-supplied
|
|
53
|
+
`signal`) into `fetch` and other cancelable APIs instead of hand-rolled
|
|
54
|
+
timeout races with `setTimeout` + `Promise.race`.
|
|
55
|
+
- Throw `Error` (or a subclass) with a message that names what failed and
|
|
56
|
+
the relevant value; chain the original cause with `new Error("...", {
|
|
57
|
+
cause })` rather than swallowing it or string-concatenating it into the
|
|
58
|
+
new message.
|
|
59
|
+
- Never catch an error only to `console.log` and continue as if it
|
|
60
|
+
succeeded -- rethrow, return a typed failure, or handle it for real.
|
|
61
|
+
|
|
62
|
+
## Imports and formatting
|
|
63
|
+
|
|
64
|
+
- Format and lint with the project's own configured tool (`eslint`,
|
|
65
|
+
`prettier`, `biome`) -- do not hand-format around a tool that is already
|
|
66
|
+
configured, and do not introduce a second formatter.
|
|
67
|
+
- Group imports: Node built-ins, then third-party packages, then local
|
|
68
|
+
(relative) imports, one blank line between groups -- the shape
|
|
69
|
+
`eslint-plugin-import`/`simple-import-sort` enforce when configured; run
|
|
70
|
+
it instead of hand-ordering when the project has it.
|
|
71
|
+
- Explicit `.js` extensions on relative ESM imports when
|
|
72
|
+
`moduleResolution: nodenext` requires them (Node's own ESM resolver does
|
|
73
|
+
not add extensions); match whatever the surrounding files already do.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
extends: common
|
|
3
|
+
paths: ["**/*.ts", "**/*.js", "**/*.mjs", "**/*.cjs"]
|
|
4
|
+
metadata:
|
|
5
|
+
origin: authored
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# TypeScript/JavaScript (Node.js) patterns
|
|
9
|
+
|
|
10
|
+
Idiomatic design patterns and anti-patterns for Node.js services, libraries
|
|
11
|
+
and CLIs written in TypeScript or JavaScript. Scoped to server/library/CLI
|
|
12
|
+
code; component composition patterns belong to the `react` pack.
|
|
13
|
+
|
|
14
|
+
## Idiomatic patterns
|
|
15
|
+
|
|
16
|
+
- Validate external input (HTTP body, CLI args, env vars, file content) at
|
|
17
|
+
the boundary where it enters the process, with a schema library (`zod`,
|
|
18
|
+
`valibot`, `ajv`) if the project already has one, or explicit checks if
|
|
19
|
+
not -- do not let unvalidated `unknown` data flow deep into business
|
|
20
|
+
logic and get treated as trusted.
|
|
21
|
+
- Use dependency injection (constructor/factory parameters) for anything
|
|
22
|
+
that talks to the outside world (DB client, HTTP client, clock, RNG) so
|
|
23
|
+
it can be swapped for a test double -- do not reach for a global
|
|
24
|
+
singleton in code that needs to be testable.
|
|
25
|
+
- Prefer small, composable functions over a class hierarchy when there is
|
|
26
|
+
no shared mutable state to encapsulate; reach for a class specifically
|
|
27
|
+
when you need to hold state across calls (a connection pool, a cache).
|
|
28
|
+
- Use `Array.prototype` methods (`map`/`filter`/`reduce`/`flatMap`) for
|
|
29
|
+
data transforms instead of manual index loops with push, unless a hot
|
|
30
|
+
loop's profiling shows the allocation cost matters.
|
|
31
|
+
- Return a discriminated union (`{ ok: true, value } | { ok: false, error
|
|
32
|
+
}`) or throw a typed error class for an operation with an expected
|
|
33
|
+
failure mode -- do not overload a return value's meaning with `null`/
|
|
34
|
+
`undefined`/`-1` for both "not found" and "failed".
|
|
35
|
+
- Use `EventEmitter`/`AsyncIterator` for a genuine stream of events over
|
|
36
|
+
time; do not reach for either to model a single async result -- that is
|
|
37
|
+
what a `Promise` is for.
|
|
38
|
+
|
|
39
|
+
## Anti-patterns to flag
|
|
40
|
+
|
|
41
|
+
- **God module / barrel re-export cycle**: an `index.ts` that re-exports
|
|
42
|
+
everything from a package and gets imported back into one of the modules
|
|
43
|
+
it re-exports -- creates a circular dependency the bundler/`tsc` may
|
|
44
|
+
tolerate but that breaks initialization order at runtime.
|
|
45
|
+
- **Synchronous work in an async-looking function**: an `async function`
|
|
46
|
+
whose body is entirely synchronous CPU work with no `await` -- it still
|
|
47
|
+
blocks the event loop exactly like a non-async function; the `async`
|
|
48
|
+
keyword adds a microtask, not a thread.
|
|
49
|
+
- **Manual promise construction around an already-async API**: wrapping a
|
|
50
|
+
callback-based Node API in `new Promise(...)` when `node:util`'s
|
|
51
|
+
`promisify` or the API's own `.promises`/`fs/promises` variant already
|
|
52
|
+
exists -- duplicates logic the platform maintains for you.
|
|
53
|
+
- **Mutating a shared config/options object**: a function that receives an
|
|
54
|
+
options object and mutates it in place instead of returning a new one --
|
|
55
|
+
surprises every other caller holding a reference to the same object.
|
|
56
|
+
- **Deep relative import chains** (`../../../../lib/x`) reaching across
|
|
57
|
+
module boundaries instead of a package-level export -- signals the
|
|
58
|
+
module boundary itself is wrong, not that the import needs a path alias.
|
|
59
|
+
- **try/catch that only rethrows the same error unchanged**: adds a stack
|
|
60
|
+
frame and nothing else; either add context (`cause`, a wrapped error
|
|
61
|
+
type) or remove the try/catch.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
extends: common
|
|
3
|
+
paths: ["**/*.ts", "**/*.js", "**/*.mjs", "**/*.cjs"]
|
|
4
|
+
metadata:
|
|
5
|
+
origin: authored
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# TypeScript/JavaScript (Node.js) security
|
|
9
|
+
|
|
10
|
+
Node.js-specific risks beyond the OWASP baseline in the common rules --
|
|
11
|
+
process/OS-level surface (child processes, the filesystem, the module
|
|
12
|
+
loader) that a Node runtime exposes and a generic web-security checklist
|
|
13
|
+
does not name directly.
|
|
14
|
+
|
|
15
|
+
## Command and process execution
|
|
16
|
+
|
|
17
|
+
- Never build a shell command string from untrusted input and pass it to
|
|
18
|
+
`child_process.exec`/`execSync` -- the shell reinterprets `;`, `|`, `` ` ``,
|
|
19
|
+
`$()` in the input. Use `execFile`/`execFileSync`/`spawn` with the
|
|
20
|
+
command and an **argument array** (`spawn("git", ["log", userBranch])`),
|
|
21
|
+
never string-concatenated into one command line.
|
|
22
|
+
- If `shell: true` is passed to `spawn`/`exec` at all, treat every argument
|
|
23
|
+
as attacker-controlled and reject/escape it -- prefer removing `shell:
|
|
24
|
+
true` over trying to escape correctly.
|
|
25
|
+
|
|
26
|
+
## Filesystem
|
|
27
|
+
|
|
28
|
+
- Resolve a user-supplied path with `path.resolve`/`path.join` against a
|
|
29
|
+
fixed root, then verify the result still starts with that root
|
|
30
|
+
(`resolved.startsWith(root + path.sep)`) before any `fs` call --
|
|
31
|
+
otherwise `../../etc/passwd`-style traversal escapes the intended
|
|
32
|
+
directory.
|
|
33
|
+
- Never pass an unvalidated path straight from a request/CLI arg to
|
|
34
|
+
`fs.readFile`/`fs.writeFile`/`fs.unlink` without that containment check.
|
|
35
|
+
|
|
36
|
+
## Data handling
|
|
37
|
+
|
|
38
|
+
- Guard against prototype pollution when merging/assigning JSON into an
|
|
39
|
+
existing object (`Object.assign`, a hand-rolled deep merge, or an older
|
|
40
|
+
`lodash.merge`): reject or strip `__proto__`, `constructor`, and
|
|
41
|
+
`prototype` keys, or use `Object.create(null)`/`structuredClone` for the
|
|
42
|
+
target instead of a plain object literal.
|
|
43
|
+
- Never pass untrusted input to `eval`, `new Function(...)`, or a `vm`
|
|
44
|
+
module context expecting it to sandbox safely -- Node's `vm` module is
|
|
45
|
+
not a security boundary against a determined attacker; use a real
|
|
46
|
+
out-of-process sandbox if untrusted code must run at all.
|
|
47
|
+
- Treat any `RegExp` built from user input, or a hand-written pattern with
|
|
48
|
+
nested quantifiers (`(a+)+`, `(a|a)*`), as a ReDoS risk on
|
|
49
|
+
attacker-controlled input length -- prefer a linear-time match, an
|
|
50
|
+
input length cap before the regex runs, or a known-safe regex engine.
|
|
51
|
+
|
|
52
|
+
## Network and secrets
|
|
53
|
+
|
|
54
|
+
- Validate and allowlist the target of any outbound `fetch`/`http(s)`
|
|
55
|
+
request built from user input (a URL, hostname, or webhook target) --
|
|
56
|
+
an unchecked outbound request lets an attacker probe internal services
|
|
57
|
+
(SSRF), including cloud metadata endpoints (`169.254.169.254`).
|
|
58
|
+
- Never `console.log`/log a request body, header, or env var wholesale in
|
|
59
|
+
a path that might carry a token, password, or API key -- log an
|
|
60
|
+
identifier (user id, request id), not the credential-bearing payload.
|
|
61
|
+
- Run `npm audit` (or the project's package manager's equivalent) and keep
|
|
62
|
+
the lockfile committed and in sync with `package.json`; do not add a
|
|
63
|
+
dependency with a known-critical advisory without a documented reason.
|
|
64
|
+
|
|
65
|
+
## Runtime posture
|
|
66
|
+
|
|
67
|
+
- Where the deployment target supports it, know that Node's permission
|
|
68
|
+
model (`--permission` plus `--allow-fs-read`/`--allow-fs-write`/
|
|
69
|
+
`--allow-child-process`) exists to restrict what a process may touch --
|
|
70
|
+
flag when a service handling untrusted input runs with no such
|
|
71
|
+
restriction and no containerization either.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
extends: common
|
|
3
|
+
paths: ["**/*.ts", "**/*.js", "**/*.mjs", "**/*.cjs"]
|
|
4
|
+
metadata:
|
|
5
|
+
origin: authored
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# TypeScript/JavaScript (Node.js) testing
|
|
9
|
+
|
|
10
|
+
Test layout, runner and determinism conventions for Node.js server/library/
|
|
11
|
+
CLI code. Discover the project's actual runner before writing anything --
|
|
12
|
+
`node:test`, Vitest, Jest and `bun test` all exist in active use and are
|
|
13
|
+
not interchangeable in syntax or config.
|
|
14
|
+
|
|
15
|
+
## Layout and runner
|
|
16
|
+
|
|
17
|
+
- Discover the runner from `package.json`'s `scripts.test`, `devDependencies`,
|
|
18
|
+
and any `vitest.config.*`/`jest.config.*` before writing a test --
|
|
19
|
+
`describe`/`it`/`test` globals differ in import source (`node:test`,
|
|
20
|
+
`vitest`, or Jest's ambient globals) even though the call shape looks
|
|
21
|
+
similar.
|
|
22
|
+
- Match the project's existing test location convention: co-located
|
|
23
|
+
`*.test.ts`/`*.spec.ts` next to the source file, or a parallel `test/`/
|
|
24
|
+
`__tests__/` tree -- do not introduce the other layout alongside it.
|
|
25
|
+
- For `node:test`, run with `node --test` (or the project's npm script
|
|
26
|
+
wrapping it); it needs no extra dependency and ships in Node itself.
|
|
27
|
+
|
|
28
|
+
## Fixtures and mocking
|
|
29
|
+
|
|
30
|
+
- Mock at the process boundary (network calls, the filesystem, a DB
|
|
31
|
+
client, `Date.now`/timers) -- not an internal function one module over,
|
|
32
|
+
which only checks that two mocks agree with each other.
|
|
33
|
+
- Use the runner's own timer mocking (`node:test`'s `mock.timers`,
|
|
34
|
+
Vitest's `vi.useFakeTimers()`, Jest's `jest.useFakeTimers()`) for any
|
|
35
|
+
test that depends on `setTimeout`/`setInterval`/`Date.now` -- a test
|
|
36
|
+
that waits on a real timer is slow and, under load, flaky.
|
|
37
|
+
- Use `node:test`'s `mock.fn()`/`mock.method()` (or the runner's
|
|
38
|
+
equivalent) instead of hand-rolled spy objects when the runner ships
|
|
39
|
+
one already.
|
|
40
|
+
|
|
41
|
+
## Determinism
|
|
42
|
+
|
|
43
|
+
- Async tests must `await` every assertion-relevant promise; a test
|
|
44
|
+
function that returns before its assertions run reports green
|
|
45
|
+
regardless of what the assertions found.
|
|
46
|
+
- Pass the test's own `AbortSignal` (`t.signal` in `node:test`, or the
|
|
47
|
+
runner's equivalent) into any `fetch`/cancelable call a test makes, so a
|
|
48
|
+
test that times out does not leave the request running past it.
|
|
49
|
+
- Never depend on test execution order or on state a previous test left
|
|
50
|
+
behind (a shared in-memory array, a module-level counter) -- each test
|
|
51
|
+
sets up and tears down its own state.
|
|
52
|
+
- A flaky test (timing-, network-, or order-dependent) gets fixed at the
|
|
53
|
+
dependency it is racing, not wrapped in a retry or a longer timeout.
|
|
54
|
+
|
|
55
|
+
## Coverage expectations
|
|
56
|
+
|
|
57
|
+
- Every new/changed exported function, class method, and CLI command gets
|
|
58
|
+
at least: one happy-path case, one edge case (empty/`null`/`undefined`/
|
|
59
|
+
boundary value), and one error case that asserts the thrown error type
|
|
60
|
+
or message, not just that something threw.
|
|
61
|
+
- A bug fix ships with a regression test that fails on the pre-fix code
|
|
62
|
+
and passes after -- without one, the fix has no evidence it addressed
|
|
63
|
+
the reported behavior.
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nodejs-build-fix
|
|
3
|
+
description: "Use when resolving `tsc` type errors, module resolution failures (ESM/CJS, moduleResolution nodenext/bundler, `type: module`, exports maps), or lint/test failures blocking a Node.js TypeScript/JavaScript build. Applies the smallest root-cause fix and never silences the checker with @ts-ignore, any, or eslint-disable. Not for Go/Rust/Python build failures, and not for implementing new features (use nodejs-implementation)."
|
|
4
|
+
triggers:
|
|
5
|
+
- "fix this tsc type error"
|
|
6
|
+
- "resolve this module not found error in Node"
|
|
7
|
+
- "fix ESM/CJS import error"
|
|
8
|
+
- "the build fails with moduleResolution error"
|
|
9
|
+
- "fix this eslint failure blocking CI"
|
|
10
|
+
- "package.json exports map is breaking the build"
|
|
11
|
+
metadata:
|
|
12
|
+
origin: authored
|
|
13
|
+
category: build-fix
|
|
14
|
+
version: "1.0.0"
|
|
15
|
+
compatible_harnesses: "claude,codex,cursor,zed,opencode"
|
|
16
|
+
license: "MIT"
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# Node.js build-fix (tsc / module resolution / lint)
|
|
20
|
+
|
|
21
|
+
Resolve a `tsc` type error, module resolution failure, or lint/test
|
|
22
|
+
failure blocking a Node.js TypeScript/JavaScript build. Applies the
|
|
23
|
+
smallest change that fixes the actual root cause -- never a change that
|
|
24
|
+
merely makes the checker stop complaining. See `rules/coding-style.mdc`
|
|
25
|
+
for the typing/module conventions a correct fix should restore.
|
|
26
|
+
|
|
27
|
+
## Workflow
|
|
28
|
+
|
|
29
|
+
### Step 1: Reproduce the failure
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npx tsc --noEmit
|
|
33
|
+
npx eslint .
|
|
34
|
+
npm test
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Run the project's own `package.json` scripts (`build`, `lint`, `test`) if
|
|
38
|
+
they differ from the above -- they may wrap these with project-specific
|
|
39
|
+
flags (path mapping, project references). Capture the exact error message
|
|
40
|
+
and file:line; do not guess at the cause from the symptom alone.
|
|
41
|
+
|
|
42
|
+
### Step 2: Classify the failure
|
|
43
|
+
|
|
44
|
+
- **Type error** (`tsc`): a genuine type mismatch, a missing property, an
|
|
45
|
+
incompatible generic instantiation, or a `noImplicitAny` violation.
|
|
46
|
+
- **Module resolution error**: `Cannot find module`, `has no exported
|
|
47
|
+
member`, an ESM/CJS interop error (`require() of ES Module`, `Unknown
|
|
48
|
+
file extension`), or an `exports` map mismatch.
|
|
49
|
+
- **Lint error**: an `eslint` rule violation -- read the rule name in the
|
|
50
|
+
output, not just the message.
|
|
51
|
+
- **Test failure**: an assertion failure or a runner-level error (setup
|
|
52
|
+
crash, timeout).
|
|
53
|
+
|
|
54
|
+
### Step 3: Find the root cause
|
|
55
|
+
|
|
56
|
+
**Type errors**: read the actual inferred type at the error site (hover
|
|
57
|
+
equivalent: trace the value back to its declaration or the function that
|
|
58
|
+
returned it) before changing anything. A type error is usually telling
|
|
59
|
+
the truth about a real mismatch, not a checker false positive.
|
|
60
|
+
|
|
61
|
+
**Module resolution**: check `package.json`'s `"type"` field,
|
|
62
|
+
`tsconfig.json`'s `moduleResolution`, and whether the failing import
|
|
63
|
+
crosses an ESM/CJS boundary (a CJS package with no ESM build, imported
|
|
64
|
+
from ESM code, or vice versa). Check the target package's own `exports`
|
|
65
|
+
map in its `package.json` for what subpaths it actually publishes.
|
|
66
|
+
|
|
67
|
+
**Lint**: read what the specific rule enforces (not just its name) before
|
|
68
|
+
changing code to satisfy it -- some rules require a structural change
|
|
69
|
+
(e.g. `no-floating-promises` wants an `await`, not a suppression).
|
|
70
|
+
|
|
71
|
+
**Test failures**: determine whether the test is wrong (asserts stale
|
|
72
|
+
behavior) or the source is wrong (behavior regressed) before touching
|
|
73
|
+
either -- read the test's intent from its name and assertions first.
|
|
74
|
+
|
|
75
|
+
### Step 4: Apply the smallest correct fix
|
|
76
|
+
|
|
77
|
+
- A type error: fix the actual type mismatch (correct the signature, add
|
|
78
|
+
the missing property, narrow the union) -- not a suppression.
|
|
79
|
+
- A module resolution error: fix the import path/extension, the
|
|
80
|
+
`tsconfig.json` setting that genuinely matches the project's runtime
|
|
81
|
+
target, or the `package.json` `exports`/`type` field -- not a blanket
|
|
82
|
+
`moduleResolution: "node"` downgrade that papers over the real
|
|
83
|
+
ESM/CJS boundary issue.
|
|
84
|
+
- A lint error: change the code to satisfy the rule's actual intent.
|
|
85
|
+
- A test failure: fix the source if behavior regressed, or fix the test if
|
|
86
|
+
its expectation was stale -- state which, and why, in the report.
|
|
87
|
+
|
|
88
|
+
### Step 5: Verify and report
|
|
89
|
+
|
|
90
|
+
Re-run the exact command from Step 1; confirm it now exits 0. Report the
|
|
91
|
+
root cause and the fix, not just "error resolved".
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
Fixed: src/lib/orderQueue.ts:18
|
|
95
|
+
Root cause: `OrderQueue.push` typed its callback parameter as `any`,
|
|
96
|
+
masking a real mismatch where callers passed `OrderEvent` but the queue
|
|
97
|
+
expected `QueueItem`.
|
|
98
|
+
Fix: added the `QueueItem` mapping in `toQueueItem()`, removed the `any`.
|
|
99
|
+
Verified: tsc --noEmit exits 0.
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Rules
|
|
103
|
+
|
|
104
|
+
- Follow `rules/coding-style.mdc` for the typing/module conventions a fix
|
|
105
|
+
must restore, not just silence.
|
|
106
|
+
- ALWAYS fix the root cause with the smallest change; never widen the fix
|
|
107
|
+
beyond the file(s) the failure actually touches.
|
|
108
|
+
- NEVER use `@ts-ignore`, an undocumented `@ts-expect-error`, a cast to
|
|
109
|
+
`any`, or an `eslint-disable` comment to make an error/warning
|
|
110
|
+
disappear.
|
|
111
|
+
- NEVER flip `strict`, `noImplicitAny`, `skipLibCheck`, or widen
|
|
112
|
+
`moduleResolution` in `tsconfig.json` just to make a specific error go
|
|
113
|
+
away -- a tsconfig change is only correct when it fixes a genuine
|
|
114
|
+
project-wide misconfiguration, and it needs to be called out explicitly
|
|
115
|
+
as such in the report.
|
|
116
|
+
- NEVER delete or skip a failing test to turn the suite green.
|
|
117
|
+
|
|
118
|
+
## Red Flags
|
|
119
|
+
|
|
120
|
+
| Rationalization | Why it is wrong |
|
|
121
|
+
|---|---|
|
|
122
|
+
| "I'll just add `@ts-ignore` above this line, it's probably a false positive" | `tsc` is almost never wrong about a real mismatch; verify the type before assuming the checker is broken |
|
|
123
|
+
| "I'll cast to `any` here to unblock the build, someone can type it properly later" | The build-fix skill's whole purpose is the properly-typed fix; `any` defers the real work indefinitely |
|
|
124
|
+
| "eslint-disable this line, the rule doesn't apply here" | If the rule genuinely does not apply, that is a project-level rule config change to propose, not a per-line suppression buried in an unrelated fix |
|
|
125
|
+
| "This test is flaky, I'll just skip it to unblock CI" | Skipping a failing test does not fix the build, it hides a real signal; find the root cause or report it unresolved |
|
|
126
|
+
|
|
127
|
+
## Verification
|
|
128
|
+
|
|
129
|
+
Do not report the fix done until all of the following hold:
|
|
130
|
+
|
|
131
|
+
- The exact command that reproduced the failure in Step 1 now exits 0.
|
|
132
|
+
- No `@ts-ignore`, `@ts-expect-error` (without a linked issue already
|
|
133
|
+
present before this fix), `any` cast, or `eslint-disable` was added.
|
|
134
|
+
- No unrelated `tsconfig.json`/`eslint` config was loosened.
|
|
135
|
+
- The report states the actual root cause, not just "fixed the error".
|
|
136
|
+
- `git status` shows changes confined to the files the root cause
|
|
137
|
+
required.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"triggers": {
|
|
3
|
+
"positive": [
|
|
4
|
+
"Fix this tsc error: Type 'string | undefined' is not assignable to type 'string'",
|
|
5
|
+
"Resolve this Node.js 'Cannot find module' error after adding a new import",
|
|
6
|
+
"Fix this require() of ES Module error in our Node service",
|
|
7
|
+
"The build fails with a moduleResolution nodenext error on this import",
|
|
8
|
+
"Fix this eslint no-floating-promises failure blocking CI",
|
|
9
|
+
"package.json exports map is breaking the build with ERR_PACKAGE_PATH_NOT_EXPORTED"
|
|
10
|
+
],
|
|
11
|
+
"negative": [
|
|
12
|
+
"go vet ./... is failing on this package, help resolve the compile error",
|
|
13
|
+
"Write a CLI command in this Node.js project that lists pending jobs from the queue",
|
|
14
|
+
"Upgrade this codebase from React 18 to React 19 and fix the deprecated lifecycle warnings",
|
|
15
|
+
"Review this diff for floating promises and unhandled rejections",
|
|
16
|
+
"Write vitest tests to cover this new order calculation function",
|
|
17
|
+
"Fix this mypy type error in the Python data pipeline"
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
"scenarios": [
|
|
21
|
+
{
|
|
22
|
+
"id": "no-ts-ignore-suppression",
|
|
23
|
+
"prompt": "tsc reports: Property 'total' does not exist on type 'OrderDraft'. What's the right way to fix this?",
|
|
24
|
+
"strictness": "high",
|
|
25
|
+
"expected_behavior": [
|
|
26
|
+
{
|
|
27
|
+
"grader": "judge",
|
|
28
|
+
"rubric": "A correct answer treats the tsc error as a genuine mismatch between the OrderDraft type and code that reads a total property from it, and fixes the type contract (or the code reading the wrong property) rather than silencing the checker.",
|
|
29
|
+
"pass_criteria": [
|
|
30
|
+
"Names the exact fix: adds a `total: number` (or the correctly-typed) property to the OrderDraft type/interface -- a plain field, or a `get total(): number` accessor that computes/derives it, both count, since either way the type now genuinely declares a typed, non-`any`, non-suppressed `total` -- or names the exact property the code should read instead of total",
|
|
31
|
+
"Shows the corrected type declaration or corrected property-access code, not just a statement of intent that the type will be fixed"
|
|
32
|
+
],
|
|
33
|
+
"fail_criteria": [
|
|
34
|
+
"Recommends @ts-ignore or an undocumented @ts-expect-error above the line as the fix",
|
|
35
|
+
"Recommends casting the value to `any` (e.g. `(order as any).total`) instead of fixing the type declaration -- naming @ts-ignore or `any` only to warn against them as part of a correct fix does not count as this failure"
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"calibration": {
|
|
40
|
+
"known_right": "The error means the OrderDraft type genuinely doesn't have a total property, but the code reads it. Don't reach for @ts-ignore or cast to any -- that just hides a real mismatch instead of fixing it. First check where total actually comes from. If every OrderDraft should carry a running total, add it to the type so the type reflects what the object actually holds:\n\ninterface OrderDraft {\n items: LineItem[];\n total: number;\n}\n\nIf total is meant to be derived instead (e.g. summed from line items), don't add it to the type at all -- read the correct property and compute it instead of reading a nonexistent one:\n\nconst total = order.items.reduce((sum, item) => sum + item.price, 0);\n\nA third, equally valid shape: a `get total(): number` accessor declared on the interface/class itself, computing the value in place, rather than a plain stored field or an external free function -- structurally it still adds a typed, non-`any`, non-suppressed `total` that satisfies the checker.\n\nEither way, trace the value back to where OrderDraft objects are constructed, confirm which case applies, then apply that fix. After the change, re-run tsc --noEmit and confirm it exits clean with no new suppressions added anywhere in the diff.",
|
|
41
|
+
"known_wrong": "Easiest fix: put // @ts-ignore on the line above order.total so tsc stops complaining, or just type it as `any` for now and cast it with (order as any).total if you want it inline. This unblocks the build immediately without having to touch the OrderDraft type definition. You can always come back and add the real property later once someone has time to figure out where total should come from -- for now this keeps CI green and doesn't risk breaking anything else in the type.",
|
|
42
|
+
"vague": "Fix the OrderDraft type so it matches what the code expects, instead of hiding the error with a suppression. That keeps the checker honest and avoids papering over a real mismatch.",
|
|
43
|
+
"subtle_wrong": "The type checker is right that total doesn't exist on OrderDraft, so I widened the local usage with a cast: const draft = order as OrderDraft & { total: number }; and used draft.total at the call site. This avoids any and keeps most of the type safety while unblocking the build; I didn't touch the shared OrderDraft interface since I wasn't sure if other call sites expect total to be absent."
|
|
44
|
+
},
|
|
45
|
+
"anti_patterns": ["@ts-ignore", "`any`"]
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"id": "reproduce-before-fix",
|
|
49
|
+
"prompt": "The Node.js build is failing but I haven't run anything yet. What's the first step to fix it?",
|
|
50
|
+
"strictness": "high",
|
|
51
|
+
"expected_behavior": [
|
|
52
|
+
{
|
|
53
|
+
"grader": "judge",
|
|
54
|
+
"rubric": "A correct answer's first step is to reproduce the failure by actually running the project's build/lint/test commands and reading the exact error message, rather than guessing at a fix from the symptom alone.",
|
|
55
|
+
"pass_criteria": [
|
|
56
|
+
"Names the specific command to run first (e.g. npx tsc --noEmit, npx eslint ., npm test, or the project's own package.json build/lint/test script) before proposing any fix -- not just 'run the build' in the abstract",
|
|
57
|
+
"States the goal of capturing the exact error message and file:line before changing any code"
|
|
58
|
+
],
|
|
59
|
+
"fail_criteria": [
|
|
60
|
+
"Proposes a fix (dependency bump, config change, lockfile deletion) before running the failing command to see the actual error",
|
|
61
|
+
"Recommends loosening tsconfig settings like moduleResolution or strict as a first move instead of reproducing and diagnosing the failure"
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
"calibration": {
|
|
66
|
+
"known_right": "Before touching any code, reproduce the failure yourself: run npx tsc --noEmit, npx eslint ., and npm test (or whatever the project's own package.json build/lint/test scripts wrap these with, since they may add path mapping or project references). Capture the exact error message and the file:line it points at -- don't guess at the cause from a vague description of 'the build is failing'. Once you have the real output, classify what kind of failure it is: a genuine tsc type error, a module resolution error (ESM/CJS interop, Cannot find module), an eslint rule violation, or a test failure. Only after you've seen the actual error and traced the value or import back to its source should you start forming a fix -- a type error is usually telling the truth about a real mismatch, not a checker false positive, so understanding it precisely first prevents a wrong fix or an unnecessary suppression.",
|
|
67
|
+
"known_wrong": "Since it's a Node build and these usually break from an outdated dependency, I'd just bump all the devDependencies to their latest versions and delete the lockfile, then reinstall -- that usually clears up whatever's stale. If it's still red after that, loosening tsconfig.json's moduleResolution to \"node\" or turning off strict mode is a quick way to get a clean build while you figure out the real problem later. No need to run anything first; these are the usual suspects for a broken Node build.",
|
|
68
|
+
"vague": "Before changing anything, I'd make sure to actually see what's failing and understand the error before jumping to a fix.",
|
|
69
|
+
"subtle_wrong": "First run the test suite to see what's currently broken. If the failure isn't immediately obvious from that output, it's usually faster to go ahead and bump the flagged dependency to its latest version, since an outdated package is the most common cause of a broken Node build -- you can always dig into the exact error afterward if the bump doesn't clear it up."
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
}
|