@ahumandev/autocode 0.0.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/LICENSE.md +21 -0
- package/README.md +379 -0
- package/dist/agents/index.d.ts +25 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.test.d.ts +2 -0
- package/dist/agents/index.test.d.ts.map +1 -0
- package/dist/agents/prompts/assist.d.ts +2 -0
- package/dist/agents/prompts/assist.d.ts.map +1 -0
- package/dist/agents/prompts/assist_git_conflict.d.ts +2 -0
- package/dist/agents/prompts/assist_git_conflict.d.ts.map +1 -0
- package/dist/agents/prompts/assist_troubleshoot.d.ts +2 -0
- package/dist/agents/prompts/assist_troubleshoot.d.ts.map +1 -0
- package/dist/agents/prompts/auto.d.ts +2 -0
- package/dist/agents/prompts/auto.d.ts.map +1 -0
- package/dist/agents/prompts/auto_feature.d.ts +2 -0
- package/dist/agents/prompts/auto_feature.d.ts.map +1 -0
- package/dist/agents/prompts/auto_general.d.ts +2 -0
- package/dist/agents/prompts/auto_general.d.ts.map +1 -0
- package/dist/agents/prompts/auto_refactor.d.ts +2 -0
- package/dist/agents/prompts/auto_refactor.d.ts.map +1 -0
- package/dist/agents/prompts/auto_research.d.ts +2 -0
- package/dist/agents/prompts/auto_research.d.ts.map +1 -0
- package/dist/agents/prompts/auto_review_api.d.ts +2 -0
- package/dist/agents/prompts/auto_review_api.d.ts.map +1 -0
- package/dist/agents/prompts/auto_review_ui.d.ts +2 -0
- package/dist/agents/prompts/auto_review_ui.d.ts.map +1 -0
- package/dist/agents/prompts/auto_test.d.ts +2 -0
- package/dist/agents/prompts/auto_test.d.ts.map +1 -0
- package/dist/agents/prompts/auto_troubleshoot.d.ts +2 -0
- package/dist/agents/prompts/auto_troubleshoot.d.ts.map +1 -0
- package/dist/agents/prompts/design.d.ts +2 -0
- package/dist/agents/prompts/design.d.ts.map +1 -0
- package/dist/agents/prompts/document_agents.d.ts +2 -0
- package/dist/agents/prompts/document_agents.d.ts.map +1 -0
- package/dist/agents/prompts/document_code.d.ts +2 -0
- package/dist/agents/prompts/document_code.d.ts.map +1 -0
- package/dist/agents/prompts/document_conventions.d.ts +2 -0
- package/dist/agents/prompts/document_conventions.d.ts.map +1 -0
- package/dist/agents/prompts/document_install.d.ts +2 -0
- package/dist/agents/prompts/document_install.d.ts.map +1 -0
- package/dist/agents/prompts/document_prd.d.ts +2 -0
- package/dist/agents/prompts/document_prd.d.ts.map +1 -0
- package/dist/agents/prompts/document_ux.d.ts +2 -0
- package/dist/agents/prompts/document_ux.d.ts.map +1 -0
- package/dist/agents/prompts/execute_author.d.ts +2 -0
- package/dist/agents/prompts/execute_author.d.ts.map +1 -0
- package/dist/agents/prompts/execute_code.d.ts +2 -0
- package/dist/agents/prompts/execute_code.d.ts.map +1 -0
- package/dist/agents/prompts/execute_debug.d.ts +2 -0
- package/dist/agents/prompts/execute_debug.d.ts.map +1 -0
- package/dist/agents/prompts/execute_document.d.ts +2 -0
- package/dist/agents/prompts/execute_document.d.ts.map +1 -0
- package/dist/agents/prompts/execute_excel.d.ts +2 -0
- package/dist/agents/prompts/execute_excel.d.ts.map +1 -0
- package/dist/agents/prompts/execute_git_commit.d.ts +2 -0
- package/dist/agents/prompts/execute_git_commit.d.ts.map +1 -0
- package/dist/agents/prompts/execute_os.d.ts +2 -0
- package/dist/agents/prompts/execute_os.d.ts.map +1 -0
- package/dist/agents/prompts/execute_script.d.ts +2 -0
- package/dist/agents/prompts/execute_script.d.ts.map +1 -0
- package/dist/agents/prompts/query_architect.d.ts +2 -0
- package/dist/agents/prompts/query_architect.d.ts.map +1 -0
- package/dist/agents/prompts/query_browser.d.ts +2 -0
- package/dist/agents/prompts/query_browser.d.ts.map +1 -0
- package/dist/agents/prompts/query_code.d.ts +2 -0
- package/dist/agents/prompts/query_code.d.ts.map +1 -0
- package/dist/agents/prompts/query_db.d.ts +2 -0
- package/dist/agents/prompts/query_db.d.ts.map +1 -0
- package/dist/agents/prompts/query_excel.d.ts +2 -0
- package/dist/agents/prompts/query_excel.d.ts.map +1 -0
- package/dist/agents/prompts/query_git.d.ts +2 -0
- package/dist/agents/prompts/query_git.d.ts.map +1 -0
- package/dist/agents/prompts/query_os.d.ts +2 -0
- package/dist/agents/prompts/query_os.d.ts.map +1 -0
- package/dist/agents/prompts/query_text.d.ts +2 -0
- package/dist/agents/prompts/query_text.d.ts.map +1 -0
- package/dist/agents/prompts/query_web.d.ts +2 -0
- package/dist/agents/prompts/query_web.d.ts.map +1 -0
- package/dist/agents/prompts/research.d.ts +2 -0
- package/dist/agents/prompts/research.d.ts.map +1 -0
- package/dist/agents/prompts/temp_concept.d.ts +2 -0
- package/dist/agents/prompts/temp_concept.d.ts.map +1 -0
- package/dist/agents/prompts/temp_manual.d.ts +4 -0
- package/dist/agents/prompts/temp_manual.d.ts.map +1 -0
- package/dist/agents/prompts/temp_report.d.ts +2 -0
- package/dist/agents/prompts/temp_report.d.ts.map +1 -0
- package/dist/agents/rules/caveman.d.ts +2 -0
- package/dist/agents/rules/caveman.d.ts.map +1 -0
- package/dist/agents/rules/definitions.d.ts +2 -0
- package/dist/agents/rules/definitions.d.ts.map +1 -0
- package/dist/agents/rules/error.d.ts +2 -0
- package/dist/agents/rules/error.d.ts.map +1 -0
- package/dist/agents/rules/markdown.d.ts +2 -0
- package/dist/agents/rules/markdown.d.ts.map +1 -0
- package/dist/agents/rules/planner.d.ts +2 -0
- package/dist/agents/rules/planner.d.ts.map +1 -0
- package/dist/agents/rules/question.d.ts +2 -0
- package/dist/agents/rules/question.d.ts.map +1 -0
- package/dist/agents/rules/response.d.ts +2 -0
- package/dist/agents/rules/response.d.ts.map +1 -0
- package/dist/agents/rules/swap2assist.d.ts +2 -0
- package/dist/agents/rules/swap2assist.d.ts.map +1 -0
- package/dist/agents/rules/task.d.ts +2 -0
- package/dist/agents/rules/task.d.ts.map +1 -0
- package/dist/commands/index.d.ts +19 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.test.d.ts +2 -0
- package/dist/commands/index.test.d.ts.map +1 -0
- package/dist/config.d.ts +29 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.test.d.ts +2 -0
- package/dist/config.test.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/plugin.d.ts +4 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +30676 -0
- package/dist/plugin.test.d.ts +2 -0
- package/dist/plugin.test.d.ts.map +1 -0
- package/dist/skills/author-article/SKILL.md +116 -0
- package/dist/skills/author-caveman/SKILL.md +18 -0
- package/dist/skills/author-readme/SKILL.md +199 -0
- package/dist/skills/author-rules/SKILL.md +182 -0
- package/dist/skills/author-skill/SKILL.md +78 -0
- package/dist/skills/author-tutorial/SKILL.md +24 -0
- package/dist/skills/code-java/SKILL.md +345 -0
- package/dist/skills/code-rest/SKILL.md +82 -0
- package/dist/skills/code-typescript/SKILL.md +453 -0
- package/dist/skills/execute-sandbox/SKILL.md +42 -0
- package/dist/skills/test-jest/SKILL.md +211 -0
- package/dist/skills/test-junit/SKILL.md +206 -0
- package/dist/skills/test-mockito/SKILL.md +209 -0
- package/dist/skills/test-vitest/SKILL.md +159 -0
- package/dist/tools/autocode_agent_swap.d.ts +13 -0
- package/dist/tools/autocode_agent_swap.d.ts.map +1 -0
- package/dist/tools/autocode_agent_swap.test.d.ts +2 -0
- package/dist/tools/autocode_agent_swap.test.d.ts.map +1 -0
- package/dist/tools/autocode_concept_create.d.ts +23 -0
- package/dist/tools/autocode_concept_create.d.ts.map +1 -0
- package/dist/tools/autocode_concept_list.d.ts +14 -0
- package/dist/tools/autocode_concept_list.d.ts.map +1 -0
- package/dist/tools/autocode_concept_read.d.ts +20 -0
- package/dist/tools/autocode_concept_read.d.ts.map +1 -0
- package/dist/tools/autocode_criteria.d.ts +52 -0
- package/dist/tools/autocode_criteria.d.ts.map +1 -0
- package/dist/tools/autocode_criteria.test.d.ts +2 -0
- package/dist/tools/autocode_criteria.test.d.ts.map +1 -0
- package/dist/tools/autocode_db.d.ts +80 -0
- package/dist/tools/autocode_db.d.ts.map +1 -0
- package/dist/tools/autocode_db.test.d.ts +2 -0
- package/dist/tools/autocode_db.test.d.ts.map +1 -0
- package/dist/tools/autocode_dependencies.d.ts +4 -0
- package/dist/tools/autocode_dependencies.d.ts.map +1 -0
- package/dist/tools/autocode_dependencies.test.d.ts +2 -0
- package/dist/tools/autocode_dependencies.test.d.ts.map +1 -0
- package/dist/tools/autocode_job_execute.d.ts +14 -0
- package/dist/tools/autocode_job_execute.d.ts.map +1 -0
- package/dist/tools/autocode_job_execute.test.d.ts +2 -0
- package/dist/tools/autocode_job_execute.test.d.ts.map +1 -0
- package/dist/tools/autocode_job_list.d.ts +23 -0
- package/dist/tools/autocode_job_list.d.ts.map +1 -0
- package/dist/tools/autocode_job_list.test.d.ts +3 -0
- package/dist/tools/autocode_job_list.test.d.ts.map +1 -0
- package/dist/tools/autocode_job_status.d.ts +5 -0
- package/dist/tools/autocode_job_status.d.ts.map +1 -0
- package/dist/tools/autocode_job_status.test.d.ts +2 -0
- package/dist/tools/autocode_job_status.test.d.ts.map +1 -0
- package/dist/tools/autocode_logo_find.d.ts +10 -0
- package/dist/tools/autocode_logo_find.d.ts.map +1 -0
- package/dist/tools/autocode_plan_read.d.ts +12 -0
- package/dist/tools/autocode_plan_read.d.ts.map +1 -0
- package/dist/tools/autocode_plan_save.d.ts +48 -0
- package/dist/tools/autocode_plan_save.d.ts.map +1 -0
- package/dist/tools/autocode_sandbox_cli.d.ts +23 -0
- package/dist/tools/autocode_sandbox_cli.d.ts.map +1 -0
- package/dist/tools/autocode_sandbox_create.d.ts +16 -0
- package/dist/tools/autocode_sandbox_create.d.ts.map +1 -0
- package/dist/tools/autocode_sandbox_delete.d.ts +12 -0
- package/dist/tools/autocode_sandbox_delete.d.ts.map +1 -0
- package/dist/tools/autocode_sandbox_file_tools.d.ts +9 -0
- package/dist/tools/autocode_sandbox_file_tools.d.ts.map +1 -0
- package/dist/tools/autocode_sandbox_tools.test.d.ts +2 -0
- package/dist/tools/autocode_sandbox_tools.test.d.ts.map +1 -0
- package/dist/tools/autocode_session_create.d.ts +13 -0
- package/dist/tools/autocode_session_create.d.ts.map +1 -0
- package/dist/tools/autocode_session_create.test.d.ts +2 -0
- package/dist/tools/autocode_session_create.test.d.ts.map +1 -0
- package/dist/tools/autocode_shelve.d.ts +5 -0
- package/dist/tools/autocode_shelve.d.ts.map +1 -0
- package/dist/tools/autocode_shelve.test.d.ts +2 -0
- package/dist/tools/autocode_shelve.test.d.ts.map +1 -0
- package/dist/tools/index.d.ts +324 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.test.d.ts +2 -0
- package/dist/tools/index.test.d.ts.map +1 -0
- package/dist/tools/task_external.d.ts +35 -0
- package/dist/tools/task_external.d.ts.map +1 -0
- package/dist/tools/task_external.test.d.ts +2 -0
- package/dist/tools/task_external.test.d.ts.map +1 -0
- package/dist/tools/task_resume.d.ts +12 -0
- package/dist/tools/task_resume.d.ts.map +1 -0
- package/dist/tools/task_resume.test.d.ts +2 -0
- package/dist/tools/task_resume.test.d.ts.map +1 -0
- package/dist/tools/test_context.d.ts +5 -0
- package/dist/tools/test_context.d.ts.map +1 -0
- package/dist/utils/agent_swap.d.ts +56 -0
- package/dist/utils/agent_swap.d.ts.map +1 -0
- package/dist/utils/agent_swap.test.d.ts +2 -0
- package/dist/utils/agent_swap.test.d.ts.map +1 -0
- package/dist/utils/autocode_dependencies.d.ts +44 -0
- package/dist/utils/autocode_dependencies.d.ts.map +1 -0
- package/dist/utils/autocode_sandbox_helpers.d.ts +12 -0
- package/dist/utils/autocode_sandbox_helpers.d.ts.map +1 -0
- package/dist/utils/db.d.ts +82 -0
- package/dist/utils/db.d.ts.map +1 -0
- package/dist/utils/delegate.d.ts +3 -0
- package/dist/utils/delegate.d.ts.map +1 -0
- package/dist/utils/frontmatter.d.ts +3 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/jobs.d.ts +210 -0
- package/dist/utils/jobs.d.ts.map +1 -0
- package/dist/utils/jobs.test.d.ts +2 -0
- package/dist/utils/jobs.test.d.ts.map +1 -0
- package/dist/utils/sandbox.d.ts +233 -0
- package/dist/utils/sandbox.d.ts.map +1 -0
- package/dist/utils/sandbox.test.d.ts +2 -0
- package/dist/utils/sandbox.test.d.ts.map +1 -0
- package/dist/utils/sandbox_file_tools.d.ts +34 -0
- package/dist/utils/sandbox_file_tools.d.ts.map +1 -0
- package/dist/utils/shelve.d.ts +33 -0
- package/dist/utils/shelve.d.ts.map +1 -0
- package/dist/utils/solution.d.ts +28 -0
- package/dist/utils/solution.d.ts.map +1 -0
- package/dist/utils/solution.test.d.ts +2 -0
- package/dist/utils/solution.test.d.ts.map +1 -0
- package/dist/utils/tool_permission.d.ts +2 -0
- package/dist/utils/tool_permission.d.ts.map +1 -0
- package/dist/utils/tools.d.ts +7 -0
- package/dist/utils/tools.d.ts.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-typescript
|
|
3
|
+
description: Typescript/Javascript Standards - Use this skill to learn how to update Typescript or Javascript code. This is the Java coding standard that you MUST apply to all your Typescript code or when you update `.ts` or `.js` files.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# TypeScript Coding Standard - Quick Reference
|
|
7
|
+
|
|
8
|
+
## Type Inference vs Explicit Types
|
|
9
|
+
|
|
10
|
+
**Always explicit for function signatures and returns:**
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
// ❌ AVOID: Missing return types
|
|
14
|
+
function getUserName(userId: number) {
|
|
15
|
+
return 'John';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// ✅ CORRECT: Explicit return types
|
|
19
|
+
function getUserName(userId: number): string {
|
|
20
|
+
return 'John';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function fetchData(url: string): Promise<Data> {
|
|
24
|
+
const response = await fetch(url);
|
|
25
|
+
return response.json();
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Null/Undefined Handling Pitfalls
|
|
32
|
+
|
|
33
|
+
**Confusion between optional (`?`) and union with undefined**
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
// ❌ AVOID: Using null in optional properties
|
|
37
|
+
interface User {
|
|
38
|
+
middleName: string | null; // Use undefined instead
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// ✅ CORRECT: Use undefined for optional
|
|
42
|
+
interface User {
|
|
43
|
+
middleName?: string; // Optional property
|
|
44
|
+
email: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ❌ AVOID: Unsafe access
|
|
48
|
+
function getUserEmail(user: User | null): string {
|
|
49
|
+
return user.email; // Crashes if user is null
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ✅ CORRECT: Null-safe access
|
|
53
|
+
function getUserEmail(user: User | undefined): string {
|
|
54
|
+
return user?.email ?? 'unknown@example.com';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// ✅ CORRECT: Explicit null checks
|
|
58
|
+
function process(value: string | undefined): void {
|
|
59
|
+
if (value !== undefined) {
|
|
60
|
+
console.log(value.toUpperCase());
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Structural Typing Pitfalls
|
|
68
|
+
|
|
69
|
+
**TypeScript uses structural typing (duck typing), not nominal typing**
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
// ❌ PITFALL: Structural typing can cause unexpected matches
|
|
73
|
+
interface Animal {
|
|
74
|
+
name: string;
|
|
75
|
+
makeSound(): void;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
interface Vehicle {
|
|
79
|
+
name: string;
|
|
80
|
+
makeSound(): void;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const dog = {
|
|
84
|
+
name: 'Buddy',
|
|
85
|
+
makeSound() { console.log('Woof!'); }
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const animal: Animal = dog; // OK: matches structure
|
|
89
|
+
const vehicle: Vehicle = dog; // Also OK: matches structure!
|
|
90
|
+
|
|
91
|
+
// ✅ CORRECT: Use branded types when strict matching needed
|
|
92
|
+
interface Named {
|
|
93
|
+
readonly __brand: 'Named';
|
|
94
|
+
name: string;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const namedUser: Named = {
|
|
98
|
+
__brand: 'Named',
|
|
99
|
+
name: 'John',
|
|
100
|
+
};
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## This Context Binding Issues
|
|
106
|
+
|
|
107
|
+
**Arrow functions in classes cause performance issues**
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
// ❌ AVOID: Arrow function properties (creates new function per instance)
|
|
111
|
+
class DataProcessor {
|
|
112
|
+
data: number[] = [];
|
|
113
|
+
|
|
114
|
+
process = (): void => {
|
|
115
|
+
this.data = [];
|
|
116
|
+
}; // Performance issue: function created for each instance
|
|
117
|
+
|
|
118
|
+
asyncProcess(): void {
|
|
119
|
+
Promise.resolve().then(function () {
|
|
120
|
+
this.process(); // 'this' is undefined here
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// ✅ CORRECT: Regular methods with arrow in callbacks
|
|
126
|
+
class DataProcessor {
|
|
127
|
+
private data: number[] = [];
|
|
128
|
+
|
|
129
|
+
process(newData: number[]): void {
|
|
130
|
+
this.data = newData;
|
|
131
|
+
this.validate();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
private validate(): void {
|
|
135
|
+
console.log('Data validated:', this.data);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
asyncProcess(): Promise<void> {
|
|
139
|
+
return Promise.resolve().then(() => {
|
|
140
|
+
this.process([1, 2, 3]); // Arrow function preserves 'this'
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// ✅ CORRECT: Use bind() if needed
|
|
146
|
+
class DataProcessor {
|
|
147
|
+
getCallback(): () => void {
|
|
148
|
+
return this.processCallback.bind(this);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
private processCallback(): void {
|
|
152
|
+
// implementation
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Named Exports Requirement
|
|
160
|
+
|
|
161
|
+
**Default exports are STRICTLY PROHIBITED - use named exports only**
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
// ❌ WRONG: Default export
|
|
165
|
+
export default class UserService { }
|
|
166
|
+
|
|
167
|
+
// ✅ CORRECT: Named exports
|
|
168
|
+
export class UserService { }
|
|
169
|
+
export interface User { id: number; }
|
|
170
|
+
export const DEFAULT_TIMEOUT = 5000;
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Disallowed Features
|
|
176
|
+
|
|
177
|
+
**Never use:** eval(), debugger, const enum, with keyword, wrapper classes (new Number/String/Boolean), modifying built-in prototypes.
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Cognitive Complexity Anti-Pattern
|
|
182
|
+
|
|
183
|
+
**Functions with too many nested conditions (SonarQube catches this)**
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
// ❌ SMELL: Overly complex function
|
|
187
|
+
function processOrder(order: any): void {
|
|
188
|
+
if (order.type === 'A') {
|
|
189
|
+
if (order.quantity > 10) {
|
|
190
|
+
if (order.priority === 'high') {
|
|
191
|
+
// Many more nested conditions...
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// ✅ CORRECT: Extract logic into helper functions
|
|
198
|
+
function processOrder(order: Order): void {
|
|
199
|
+
if (isHighPriorityBulkOrder(order)) {
|
|
200
|
+
applyExpressShipping(order);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function isHighPriorityBulkOrder(order: Order): boolean {
|
|
205
|
+
return order.type === 'A' && order.quantity > 10 && order.priority === 'high';
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Variable Declaration Rules
|
|
212
|
+
|
|
213
|
+
**Default to `const`, use `let` only for reassignment, never use `var`**
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
## Async/Await Common Mistakes
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
// ❌ CRITICAL BUG: Missing await
|
|
225
|
+
async function fetchData(): Promise<void> {
|
|
226
|
+
const data = fetch('/api/data'); // Missing await!
|
|
227
|
+
console.log(data); // Logs Promise, not the actual data
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// ✅ CORRECT: Use await
|
|
231
|
+
async function fetchData(): Promise<Data> {
|
|
232
|
+
const response = await fetch('/api/data');
|
|
233
|
+
if (!response.ok) {
|
|
234
|
+
throw new Error('Failed to fetch');
|
|
235
|
+
}
|
|
236
|
+
return response.json();
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// ❌ AVOID: Unhandled promise rejection
|
|
240
|
+
async function processUser(userId: number): Promise<void> {
|
|
241
|
+
const user = await getUser(userId); // No error handling
|
|
242
|
+
console.log(user);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// ✅ CORRECT: Proper error handling
|
|
246
|
+
async function processUser(userId: number): Promise<void> {
|
|
247
|
+
try {
|
|
248
|
+
const user = await getUser(userId);
|
|
249
|
+
console.log(user);
|
|
250
|
+
} catch (error) {
|
|
251
|
+
console.error('Failed to process user:', error);
|
|
252
|
+
throw error;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Type Safety Violations
|
|
260
|
+
|
|
261
|
+
**Using `any` type defeats TypeScript's purpose**
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
// ❌ AVOID: Using any
|
|
265
|
+
function process(data: any): any {
|
|
266
|
+
return data.value; // No type checking
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// ✅ CORRECT: Use specific types
|
|
270
|
+
interface DataInput {
|
|
271
|
+
value: number;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function process(data: DataInput): number {
|
|
275
|
+
return data.value;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// ✅ CORRECT: Use unknown for truly unknown types
|
|
279
|
+
function handleUnknown(data: unknown): void {
|
|
280
|
+
if (typeof data === 'object' && data !== null && 'value' in data) {
|
|
281
|
+
console.log((data as { value: any }).value);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Complex Type Simplification
|
|
289
|
+
|
|
290
|
+
**Deeply nested types are hard to maintain**
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
// ❌ AVOID: Overly complex nested types
|
|
294
|
+
type ComplexResponse = {
|
|
295
|
+
status: number;
|
|
296
|
+
data: {
|
|
297
|
+
user: {
|
|
298
|
+
id: number;
|
|
299
|
+
profile: {
|
|
300
|
+
name: string;
|
|
301
|
+
email: string;
|
|
302
|
+
settings: {
|
|
303
|
+
notifications: boolean;
|
|
304
|
+
};
|
|
305
|
+
};
|
|
306
|
+
}[];
|
|
307
|
+
};
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
// ✅ CORRECT: Break into smaller types
|
|
311
|
+
type UserSettings = {
|
|
312
|
+
notifications: boolean;
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
type UserProfile = {
|
|
316
|
+
name: string;
|
|
317
|
+
email: string;
|
|
318
|
+
settings: UserSettings;
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
type User = {
|
|
322
|
+
id: number;
|
|
323
|
+
profile: UserProfile;
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
type ApiResponse<T> = {
|
|
327
|
+
status: number;
|
|
328
|
+
data: T;
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
type UserApiResponse = ApiResponse<User[]>;
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## React-Specific Pitfalls
|
|
337
|
+
|
|
338
|
+
**Keys in lists - array indices are anti-pattern**
|
|
339
|
+
|
|
340
|
+
```typescript
|
|
341
|
+
// ❌ CRITICAL: Using array index as key
|
|
342
|
+
function UserList({ users }): JSX.Element {
|
|
343
|
+
return (
|
|
344
|
+
<ul>
|
|
345
|
+
{users.map((user, index) => (
|
|
346
|
+
<li key={index}>{user.name}</li> // Key changes when list reorders!
|
|
347
|
+
))}
|
|
348
|
+
</ul>
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// ✅ CORRECT: Use stable identifiers
|
|
353
|
+
function UserList({ users }): JSX.Element {
|
|
354
|
+
return (
|
|
355
|
+
<ul>
|
|
356
|
+
{users.map((user) => (
|
|
357
|
+
<li key={user.id}>{user.name}</li> // Stable identifier
|
|
358
|
+
))}
|
|
359
|
+
</ul>
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
**Use hooks, not class lifecycle methods**
|
|
365
|
+
|
|
366
|
+
```typescript
|
|
367
|
+
// ✅ CORRECT: Use hooks
|
|
368
|
+
function UserProfile(): JSX.Element {
|
|
369
|
+
const [user, setUser] = useState<User | null>(null);
|
|
370
|
+
|
|
371
|
+
useEffect(() => {
|
|
372
|
+
// Fetch data
|
|
373
|
+
return () => { /* Cleanup */ };
|
|
374
|
+
}, []);
|
|
375
|
+
|
|
376
|
+
return <div>{user?.name}</div>;
|
|
377
|
+
}
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
## Loop Variable Capture
|
|
383
|
+
|
|
384
|
+
**`var` in loops with callbacks creates closure bugs**
|
|
385
|
+
|
|
386
|
+
```typescript
|
|
387
|
+
// ❌ BUG: var captured by closure
|
|
388
|
+
for (var i = 0; i < 3; i++) {
|
|
389
|
+
setTimeout(() => {
|
|
390
|
+
console.log(i); // Always logs 3 (var is function-scoped)
|
|
391
|
+
}, 100);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// ✅ CORRECT: Use const with for...of
|
|
395
|
+
for (const i of [0, 1, 2]) {
|
|
396
|
+
setTimeout(() => {
|
|
397
|
+
console.log(i); // Logs 0, 1, 2 correctly
|
|
398
|
+
}, 100);
|
|
399
|
+
}
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## Security Pitfalls
|
|
405
|
+
|
|
406
|
+
**These will fail SonarQube and code reviews**
|
|
407
|
+
|
|
408
|
+
```typescript
|
|
409
|
+
// ❌ CRITICAL: XSS vulnerability
|
|
410
|
+
document.getElementById('content').innerHTML = userInput; // Raw HTML injection!
|
|
411
|
+
|
|
412
|
+
// ✅ CORRECT: Use textContent
|
|
413
|
+
document.getElementById('content').textContent = userInput;
|
|
414
|
+
|
|
415
|
+
// ❌ CRITICAL: Hard-coded credentials
|
|
416
|
+
const DB_PASSWORD = 'admin123';
|
|
417
|
+
const API_KEY = 'sk_live_abc123';
|
|
418
|
+
|
|
419
|
+
// ✅ CORRECT: Environment variables
|
|
420
|
+
const DB_PASSWORD = process.env.DB_PASSWORD;
|
|
421
|
+
const API_KEY = process.env.API_KEY;
|
|
422
|
+
|
|
423
|
+
// ❌ HOTSPOT: Logging sensitive data
|
|
424
|
+
function login(username: string, password: string): void {
|
|
425
|
+
console.log(`User ${username} logged in with ${password}`); // Logs password!
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// ✅ CORRECT: Log only non-sensitive info
|
|
429
|
+
function login(username: string, password: string): void {
|
|
430
|
+
console.log(`User ${username} logged in successfully`);
|
|
431
|
+
}
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
---
|
|
435
|
+
|
|
436
|
+
## Strict Equality
|
|
437
|
+
|
|
438
|
+
**Always use `===` and `!==`, never `==` or `!=`**
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## SonarQube Quality Gate Violations
|
|
443
|
+
|
|
444
|
+
**Common catches:** Unused variables, unreachable code, missing default cases, code duplication, overly complex functions.
|
|
445
|
+
|
|
446
|
+
Extract common logic to avoid duplication. Remove unused variables. Keep functions focused.
|
|
447
|
+
|
|
448
|
+
---
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
**Document Status:** Non-obvious mistakes and SonarQube pitfalls reference
|
|
452
|
+
**Languages:** TypeScript, JavaScript
|
|
453
|
+
**Focus:** Quick-reference for code reviewers and developers
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: execute-sandbox
|
|
3
|
+
description: Use `execute-sandbox` to get Execute Sandbox Instructions when accessing/manipulating sandboxes - run commands in, inspect, edit, copy files in isolated sandboxes.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Execute Sandbox Instructions
|
|
7
|
+
|
|
8
|
+
Use sandbox tools for isolated command execution and file inspection without changing the host project.
|
|
9
|
+
|
|
10
|
+
## Lifecycle tools
|
|
11
|
+
|
|
12
|
+
- `autocode_sandbox_cli`: run shell commands inside an existing sandbox.
|
|
13
|
+
|
|
14
|
+
## File tools
|
|
15
|
+
|
|
16
|
+
- `autocode_sandbox_read`: read files inside a sandbox.
|
|
17
|
+
- `autocode_sandbox_glob`: find sandbox files by glob.
|
|
18
|
+
- `autocode_sandbox_grep`: search sandbox file contents.
|
|
19
|
+
- `autocode_sandbox_edit`: edit sandbox files.
|
|
20
|
+
- `autocode_sandbox_copy`: copy files between local project paths and sandbox paths.
|
|
21
|
+
|
|
22
|
+
## Sandbox paths
|
|
23
|
+
|
|
24
|
+
Special mounts inside sandbox relative to Sandbox root:
|
|
25
|
+
|
|
26
|
+
- `/sandbox`: writable sandbox directory for sandbox tasks: scratch area, generated outputs, experiments, etc.
|
|
27
|
+
- `/home`: writable home directory for config files, caches, package manager state, shell history, etc.
|
|
28
|
+
- `/workspace`: read-only mount of the project workspace for inspection only.
|
|
29
|
+
|
|
30
|
+
## Path rules
|
|
31
|
+
|
|
32
|
+
- Use relative paths only.
|
|
33
|
+
- Do not use absolute paths.
|
|
34
|
+
- Do not use `..` to escape roots.
|
|
35
|
+
- Do not include NUL bytes.
|
|
36
|
+
- Local paths are relative to the project root.
|
|
37
|
+
- Sandbox paths are relative to the sandbox root.
|
|
38
|
+
- Do not copy from `/workspace`; copy from local project paths into the sandbox instead.
|
|
39
|
+
|
|
40
|
+
## Copy behavior
|
|
41
|
+
|
|
42
|
+
`autocode_sandbox_copy` copies local project files to sandbox paths, or sandbox files back to local project paths when supported. Existing destinations are not replaced unless overwrite is enabled.
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: test-jest
|
|
3
|
+
description: Use this skill when writing or fixing unit tests with Jest (TypeScript/JavaScript).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Jest Testing Skill
|
|
7
|
+
|
|
8
|
+
Jest is a widely-used JavaScript testing framework with built-in mocking, assertions, and coverage support.
|
|
9
|
+
|
|
10
|
+
## Detection
|
|
11
|
+
|
|
12
|
+
Jest is in use when:
|
|
13
|
+
- `package.json` devDependencies includes `jest` or `ts-jest` or `@types/jest`
|
|
14
|
+
- A `jest.config.js`, `jest.config.ts`, or `jest.config.json` exists
|
|
15
|
+
- Test files use `.spec.ts`, `.test.ts`, `.spec.js`, or `.test.js` extensions
|
|
16
|
+
- `package.json` has a `"jest"` configuration key
|
|
17
|
+
|
|
18
|
+
## File Structure
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
src/
|
|
22
|
+
foo.ts # production file
|
|
23
|
+
foo.spec.ts # test file (co-located)
|
|
24
|
+
# OR
|
|
25
|
+
__tests__/
|
|
26
|
+
foo.test.ts # alternative location
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Match the existing project convention.
|
|
30
|
+
|
|
31
|
+
## Basic Test Structure
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { myFunction } from './myModule'
|
|
35
|
+
|
|
36
|
+
describe('myModule', () => {
|
|
37
|
+
beforeEach(() => {
|
|
38
|
+
jest.clearAllMocks()
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
describe('myFunction', () => {
|
|
42
|
+
it('should return expected value for valid input', () => {
|
|
43
|
+
// Arrange
|
|
44
|
+
const input = 'hello'
|
|
45
|
+
|
|
46
|
+
// Build
|
|
47
|
+
const result = myFunction(input)
|
|
48
|
+
|
|
49
|
+
// Assert
|
|
50
|
+
expect(result).toBe('HELLO')
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('should throw for invalid input', () => {
|
|
54
|
+
expect(() => myFunction(null)).toThrow('Input must not be null')
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Mocking
|
|
61
|
+
|
|
62
|
+
### Mock a module
|
|
63
|
+
```typescript
|
|
64
|
+
jest.mock('./dependency', () => ({
|
|
65
|
+
fetchData: jest.fn().mockResolvedValue({ id: 1, name: 'test' }),
|
|
66
|
+
}))
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Mock a function
|
|
70
|
+
```typescript
|
|
71
|
+
const mockFn = jest.fn().mockReturnValue(42)
|
|
72
|
+
const mockAsync = jest.fn().mockResolvedValue({ ok: true })
|
|
73
|
+
const mockRejected = jest.fn().mockRejectedValue(new Error('fail'))
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Spy on a method
|
|
77
|
+
```typescript
|
|
78
|
+
const spy = jest.spyOn(obj, 'method').mockReturnValue('mocked')
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Auto mock
|
|
82
|
+
```typescript
|
|
83
|
+
jest.mock('./heavyModule') // auto-mocks all exports
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Reset mocks between tests
|
|
87
|
+
```typescript
|
|
88
|
+
beforeEach(() => {
|
|
89
|
+
jest.clearAllMocks() // clear call counts and instances
|
|
90
|
+
jest.resetAllMocks() // clear + reset implementations to undefined
|
|
91
|
+
jest.restoreAllMocks() // restore jest.spyOn originals
|
|
92
|
+
})
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Async Tests
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
it('should resolve promise', async () => {
|
|
99
|
+
const result = await someAsyncFunction()
|
|
100
|
+
expect(result).toEqual({ success: true })
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
it('should reject promise', async () => {
|
|
104
|
+
await expect(someAsyncFunction()).rejects.toThrow('error message')
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
// With done callback (legacy)
|
|
108
|
+
it('legacy callback test', (done) => {
|
|
109
|
+
fetchData((data) => {
|
|
110
|
+
expect(data).toBe('ok')
|
|
111
|
+
done()
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Timers
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
jest.useFakeTimers()
|
|
120
|
+
|
|
121
|
+
it('should debounce', () => {
|
|
122
|
+
const fn = jest.fn()
|
|
123
|
+
debounce(fn, 500)()
|
|
124
|
+
jest.advanceTimersByTime(500)
|
|
125
|
+
expect(fn).toHaveBeenCalledTimes(1)
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
afterEach(() => jest.useRealTimers())
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Common Assertions
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
expect(value).toBe(42) // strict equality (Object.is)
|
|
135
|
+
expect(value).toEqual({ a: 1 }) // deep equality
|
|
136
|
+
expect(value).toStrictEqual({ a: 1 }) // deep + checks undefined properties
|
|
137
|
+
expect(value).toBeNull()
|
|
138
|
+
expect(value).toBeUndefined()
|
|
139
|
+
expect(value).toBeDefined()
|
|
140
|
+
expect(value).toBeTruthy()
|
|
141
|
+
expect(value).toBeFalsy()
|
|
142
|
+
expect(array).toHaveLength(3)
|
|
143
|
+
expect(array).toContain('item')
|
|
144
|
+
expect(object).toHaveProperty('key', 'value')
|
|
145
|
+
expect(fn).toHaveBeenCalledWith('arg')
|
|
146
|
+
expect(fn).toHaveBeenCalledTimes(2)
|
|
147
|
+
expect(fn).toHaveBeenNthCalledWith(1, 'first arg')
|
|
148
|
+
expect(fn).not.toHaveBeenCalled()
|
|
149
|
+
expect(value).toMatchSnapshot()
|
|
150
|
+
expect(value).toMatchInlineSnapshot(`"expected"`)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## TypeScript Setup
|
|
154
|
+
|
|
155
|
+
With `ts-jest`:
|
|
156
|
+
```json
|
|
157
|
+
// jest.config.json
|
|
158
|
+
{
|
|
159
|
+
"preset": "ts-jest",
|
|
160
|
+
"testEnvironment": "node",
|
|
161
|
+
"roots": ["<rootDir>/src"]
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
With `@swc/jest` (faster):
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"transform": {
|
|
169
|
+
"^.+\.(t|j)s$": "@swc/jest"
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Running Tests
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
# Run all tests
|
|
178
|
+
npx jest
|
|
179
|
+
|
|
180
|
+
# Run with coverage
|
|
181
|
+
npx jest --coverage
|
|
182
|
+
|
|
183
|
+
# Run specific file
|
|
184
|
+
npx jest src/foo.spec.ts
|
|
185
|
+
|
|
186
|
+
# Run tests matching pattern
|
|
187
|
+
npx jest --testNamePattern="myFunction"
|
|
188
|
+
|
|
189
|
+
# Watch mode
|
|
190
|
+
npx jest --watch
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Coverage
|
|
194
|
+
|
|
195
|
+
Configure in `jest.config.js`:
|
|
196
|
+
```javascript
|
|
197
|
+
module.exports = {
|
|
198
|
+
collectCoverageFrom: ['src/**/*.ts', '!src/**/*.spec.ts'],
|
|
199
|
+
coverageThreshold: {
|
|
200
|
+
global: { lines: 80 }
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Common Pitfalls
|
|
206
|
+
|
|
207
|
+
- `jest.mock()` is hoisted to the top of the file by Babel/Jest — don't rely on variable initialization order
|
|
208
|
+
- Use `jest.fn()` over raw functions for spying — raw functions can't be tracked
|
|
209
|
+
- `toEqual` does deep equality; `toBe` uses `Object.is` (like `===`) — use `toEqual` for objects/arrays
|
|
210
|
+
- Clear mocks in `beforeEach` to prevent test pollution across test cases
|
|
211
|
+
- For TypeScript, ensure `@types/jest` is installed or use `import type { jest } from '@jest/globals'`
|