automatasaurus 0.1.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.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +543 -0
  3. package/bin/cli.js +62 -0
  4. package/package.json +39 -0
  5. package/src/commands/init.js +149 -0
  6. package/src/commands/status.js +68 -0
  7. package/src/commands/update.js +140 -0
  8. package/src/lib/block-merge.js +86 -0
  9. package/src/lib/json-merge.js +121 -0
  10. package/src/lib/manifest.js +60 -0
  11. package/src/lib/paths.js +55 -0
  12. package/src/lib/symlinks.js +127 -0
  13. package/template/CLAUDE.block.md +357 -0
  14. package/template/README.md +36 -0
  15. package/template/agents/architect/AGENT.md +167 -0
  16. package/template/agents/designer/AGENT.md +289 -0
  17. package/template/agents/developer/AGENT.md +182 -0
  18. package/template/agents/tester/AGENT.md +308 -0
  19. package/template/artifacts/discovery.md.template +193 -0
  20. package/template/artifacts/implementation-plan.md.template +119 -0
  21. package/template/commands/discovery.md +325 -0
  22. package/template/commands/work-all.md +274 -0
  23. package/template/commands/work-plan.md +169 -0
  24. package/template/commands/work.md +73 -0
  25. package/template/commands.block.md +45 -0
  26. package/template/commands.template.md +156 -0
  27. package/template/hooks/notify.sh +83 -0
  28. package/template/hooks/on-stop.sh +54 -0
  29. package/template/hooks/request-attention.sh +16 -0
  30. package/template/settings.json +85 -0
  31. package/template/skills/agent-coordination/SKILL.md +166 -0
  32. package/template/skills/code-review/SKILL.md +386 -0
  33. package/template/skills/css-standards/SKILL.md +488 -0
  34. package/template/skills/github-issues/SKILL.md +144 -0
  35. package/template/skills/github-workflow/SKILL.md +161 -0
  36. package/template/skills/infrastructure-standards/SKILL.md +189 -0
  37. package/template/skills/javascript-standards/SKILL.md +355 -0
  38. package/template/skills/notifications/SKILL.md +95 -0
  39. package/template/skills/pr-writing/SKILL.md +259 -0
  40. package/template/skills/project-commands/SKILL.md +100 -0
  41. package/template/skills/python-standards/SKILL.md +284 -0
  42. package/template/skills/requirements-gathering/SKILL.md +212 -0
  43. package/template/skills/user-stories/SKILL.md +192 -0
  44. package/template/skills/work-issue/SKILL.md +245 -0
  45. package/template/skills/workflow-orchestration/SKILL.md +271 -0
@@ -0,0 +1,161 @@
1
+ ---
2
+ name: github-workflow
3
+ description: Manages GitHub workflow including issues, PRs, labels, and reviews. Use when working with GitHub issues, creating PRs, or coordinating reviews.
4
+ ---
5
+
6
+ # GitHub Workflow Skill
7
+
8
+ Guidance for managing the development workflow through GitHub.
9
+
10
+ ## Issue State Labels
11
+
12
+ | Label | Description | When to Apply |
13
+ |-------|-------------|---------------|
14
+ | `ready` | No blocking dependencies | Issue can be picked up |
15
+ | `in-progress` | Currently being implemented | Developer starts work |
16
+ | `blocked` | Waiting on dependencies | Has unresolved blockers |
17
+ | `needs-review` | PR open, awaiting reviews | PR created |
18
+
19
+ ```bash
20
+ gh issue edit {n} --add-label "in-progress" --remove-label "ready"
21
+ gh issue edit {n} --add-label "needs-review" --remove-label "in-progress"
22
+ ```
23
+
24
+ ## Dependency Tracking
25
+
26
+ In issue body:
27
+ ```markdown
28
+ ## Dependencies
29
+ Depends on #12 (User authentication)
30
+ Depends on #15 (Database schema)
31
+ ```
32
+
33
+ Parse dependencies:
34
+ ```bash
35
+ gh issue view {n} --json body --jq '.body' | grep -oE "Depends on #[0-9]+" | grep -oE "[0-9]+"
36
+ gh issue view {dep} --json state --jq '.state'
37
+ ```
38
+
39
+ ## Agent Identification
40
+
41
+ **All GitHub interactions must include an agent identifier header.**
42
+
43
+ Format: `**[Agent Name]**` at the start of every issue body, PR description, and comment.
44
+
45
+ ## Standardized Review Comments
46
+
47
+ Since all agents share the same GitHub user, reviews use standardized comments:
48
+
49
+ **Approval:**
50
+ ```
51
+ ✅ APPROVED - [Role]
52
+ [Summary]
53
+ ```
54
+
55
+ **Changes Requested:**
56
+ ```
57
+ ❌ CHANGES REQUESTED - [Role]
58
+ [Issues to address]
59
+ ```
60
+
61
+ ## Required Reviews Per PR
62
+
63
+ | Review | When Required |
64
+ |--------|---------------|
65
+ | Architect | Always |
66
+ | Designer | If UI changes |
67
+ | Tester | Always |
68
+
69
+ ## Review Templates
70
+
71
+ ### Architect
72
+ ```bash
73
+ gh pr comment {n} --body "**[Architect]**
74
+
75
+ ✅ APPROVED - Architect
76
+
77
+ Clean architecture. LGTM."
78
+ ```
79
+
80
+ ### Designer
81
+ ```bash
82
+ gh pr comment {n} --body "**[Designer]**
83
+
84
+ ✅ APPROVED - Designer
85
+
86
+ UI looks good. Accessibility met."
87
+
88
+ # Or if not applicable:
89
+ gh pr comment {n} --body "**[Designer]** N/A - No UI changes."
90
+ ```
91
+
92
+ ### Tester
93
+ ```bash
94
+ gh pr comment {n} --body "**[Tester]**
95
+
96
+ ✅ APPROVED - Tester
97
+
98
+ **Tests:** All passing
99
+ **Manual:** Completed
100
+
101
+ Ready for merge."
102
+ ```
103
+
104
+ ### Product Owner (Merge)
105
+ ```bash
106
+ gh pr comment {n} --body "**[Product Owner]**
107
+
108
+ All required reviews complete:
109
+ - ✅ Architect
110
+ - ✅ Tester
111
+
112
+ Proceeding with merge."
113
+
114
+ gh pr merge {n} --squash --delete-branch
115
+ ```
116
+
117
+ ## PR Approval Verification
118
+
119
+ Before merge:
120
+ 1. `✅ APPROVED - Architect` present
121
+ 2. `✅ APPROVED - Tester` present
122
+ 3. `✅ APPROVED - Designer` present (if UI)
123
+ 4. No outstanding `❌ CHANGES REQUESTED`
124
+ 5. CI/tests passing
125
+
126
+ ```bash
127
+ gh pr view {n} --comments # Check for approval comments
128
+ ```
129
+
130
+ ## Labels
131
+
132
+ ### Priority
133
+ | Label | Description |
134
+ |-------|-------------|
135
+ | `priority:high` | Work first |
136
+ | `priority:medium` | Normal |
137
+ | `priority:low` | Work last |
138
+
139
+ ### Type
140
+ | Label | Description |
141
+ |-------|-------------|
142
+ | `feature` | New functionality |
143
+ | `bug` | Bug fix |
144
+ | `enhancement` | Improvement |
145
+
146
+ ## Common Commands
147
+
148
+ ```bash
149
+ # Issues
150
+ gh issue list --state open --label "ready"
151
+ gh issue view {n}
152
+ gh issue edit {n} --add-label "in-progress"
153
+
154
+ # PRs
155
+ gh pr create --title "..." --body "..."
156
+ gh pr view {n} --comments
157
+ gh pr merge {n} --squash --delete-branch
158
+
159
+ # Milestones
160
+ gh issue edit {n} --milestone "v1.0"
161
+ ```
@@ -0,0 +1,189 @@
1
+ ---
2
+ name: infrastructure-standards
3
+ description: Infrastructure, cloud, and DevOps standards. Use when setting up new projects, configuring cloud resources, or working with IaC.
4
+ ---
5
+
6
+ # Infrastructure Standards
7
+
8
+ ## New Project Preferences
9
+
10
+ When starting new projects, prefer:
11
+
12
+ - **Terraform** for Infrastructure as Code
13
+ - **GCP** (Google Cloud Platform) by default, unless otherwise specified
14
+ - **Serverless** architectures that are free when idle (Cloud Run, Cloud Functions)
15
+ - **Docker Compose** for local development
16
+
17
+ ## Terraform
18
+
19
+ ### Project Structure
20
+ ```
21
+ infrastructure/
22
+ ├── main.tf # Main configuration
23
+ ├── variables.tf # Input variables
24
+ ├── outputs.tf # Output values
25
+ ├── providers.tf # Provider configuration
26
+ ├── terraform.tfvars # Variable values (gitignored for secrets)
27
+ └── modules/ # Reusable modules
28
+ └── api/
29
+ ├── main.tf
30
+ ├── variables.tf
31
+ └── outputs.tf
32
+ ```
33
+
34
+ ### Best Practices
35
+ - Use remote state (GCS bucket for GCP)
36
+ - Lock state files to prevent concurrent modifications
37
+ - Use workspaces or separate state files for environments
38
+ - Tag all resources consistently
39
+ - Use modules for reusable infrastructure
40
+
41
+ ### GCP Provider Setup
42
+ ```hcl
43
+ terraform {
44
+ required_version = ">= 1.0"
45
+
46
+ required_providers {
47
+ google = {
48
+ source = "hashicorp/google"
49
+ version = "~> 5.0"
50
+ }
51
+ }
52
+
53
+ backend "gcs" {
54
+ bucket = "project-terraform-state"
55
+ prefix = "terraform/state"
56
+ }
57
+ }
58
+
59
+ provider "google" {
60
+ project = var.project_id
61
+ region = var.region
62
+ }
63
+ ```
64
+
65
+ ## GCP Services
66
+
67
+ ### Preferred Services (Free When Idle)
68
+
69
+ | Use Case | Service | Notes |
70
+ |----------|---------|-------|
71
+ | APIs/Backend | Cloud Run | Scale to zero, pay per request |
72
+ | Background Jobs | Cloud Functions | Event-driven, scale to zero |
73
+ | Scheduled Tasks | Cloud Scheduler + Cloud Functions | Cron-like scheduling |
74
+ | Database | Cloud SQL (small) or Firestore | Firestore has free tier |
75
+ | Storage | Cloud Storage | Pay per use |
76
+ | Auth | Firebase Auth | Free tier generous |
77
+
78
+ ### Cloud Run Example
79
+ ```hcl
80
+ resource "google_cloud_run_service" "api" {
81
+ name = "api"
82
+ location = var.region
83
+
84
+ template {
85
+ spec {
86
+ containers {
87
+ image = "gcr.io/${var.project_id}/api:latest"
88
+
89
+ resources {
90
+ limits = {
91
+ memory = "512Mi"
92
+ cpu = "1"
93
+ }
94
+ }
95
+ }
96
+ }
97
+
98
+ metadata {
99
+ annotations = {
100
+ "autoscaling.knative.dev/minScale" = "0" # Scale to zero
101
+ "autoscaling.knative.dev/maxScale" = "10"
102
+ }
103
+ }
104
+ }
105
+ }
106
+ ```
107
+
108
+ ## Docker Compose (Local Dev)
109
+
110
+ ### Standard Structure
111
+ ```yaml
112
+ # docker-compose.yml
113
+ version: "3.8"
114
+
115
+ services:
116
+ api:
117
+ build: ./api
118
+ ports:
119
+ - "8000:8000"
120
+ volumes:
121
+ - ./api:/app
122
+ environment:
123
+ - DATABASE_URL=postgresql://postgres:postgres@db:5432/app
124
+ depends_on:
125
+ - db
126
+
127
+ web:
128
+ build: ./web
129
+ ports:
130
+ - "3000:3000"
131
+ volumes:
132
+ - ./web:/app
133
+ - /app/node_modules
134
+ environment:
135
+ - VITE_API_URL=http://localhost:8000
136
+
137
+ db:
138
+ image: postgres:15
139
+ ports:
140
+ - "5432:5432"
141
+ environment:
142
+ - POSTGRES_PASSWORD=postgres
143
+ - POSTGRES_DB=app
144
+ volumes:
145
+ - postgres_data:/var/lib/postgresql/data
146
+
147
+ volumes:
148
+ postgres_data:
149
+ ```
150
+
151
+ ### Best Practices
152
+ - Use named volumes for persistent data
153
+ - Mount source code for hot reload in development
154
+ - Use `.env` files for environment variables (gitignored)
155
+ - Include health checks for dependent services
156
+ - Use `depends_on` with health conditions when needed
157
+
158
+ ## Environment Management
159
+
160
+ ### Secret Handling
161
+ - Never commit secrets to git
162
+ - Use `.env` files locally (gitignored)
163
+ - Use GCP Secret Manager for production
164
+ - Reference secrets in Terraform:
165
+
166
+ ```hcl
167
+ data "google_secret_manager_secret_version" "api_key" {
168
+ secret = "api-key"
169
+ }
170
+
171
+ resource "google_cloud_run_service" "api" {
172
+ # ...
173
+ template {
174
+ spec {
175
+ containers {
176
+ env {
177
+ name = "API_KEY"
178
+ value_from {
179
+ secret_key_ref {
180
+ name = google_secret_manager_secret.api_key.secret_id
181
+ key = "latest"
182
+ }
183
+ }
184
+ }
185
+ }
186
+ }
187
+ }
188
+ }
189
+ ```
@@ -0,0 +1,355 @@
1
+ ---
2
+ name: javascript-standards
3
+ description: JavaScript and TypeScript coding standards, conventions, and best practices. Use when writing, reviewing, or testing JS/TS code.
4
+ ---
5
+
6
+ # JavaScript/TypeScript Coding Standards
7
+
8
+ ## New Project Preferences
9
+
10
+ When starting new frontend projects, prefer:
11
+
12
+ - **React 18** with TypeScript
13
+ - **Vite** for development server
14
+ - **Parcel** for production bundling
15
+ - **shadcn/ui** for components
16
+ - **Tailwind CSS 3** for styling
17
+
18
+ ## General Preferences
19
+
20
+ - **TypeScript over JavaScript** for new code
21
+ - **ESM over CommonJS** (`import`/`export` not `require`)
22
+ - **Prettier** for formatting, **ESLint** for linting
23
+ - **Strict TypeScript** (`"strict": true` in tsconfig)
24
+
25
+ ## Style Guide
26
+
27
+ ### Formatting (Prettier defaults)
28
+ - Line length: 80-100 characters
29
+ - Single quotes for strings
30
+ - Semicolons: consistent (prefer with)
31
+ - Trailing commas: ES5 or all
32
+ - 2 space indentation
33
+
34
+ ### Naming Conventions
35
+ ```typescript
36
+ // Files: kebab-case or PascalCase for components
37
+ user-service.ts
38
+ UserProfile.tsx
39
+
40
+ // Variables and functions: camelCase
41
+ const activeUsers = [];
42
+ function getUserById(userId: string): User {}
43
+
44
+ // Classes and types: PascalCase
45
+ class UserService {}
46
+ interface UserProfile {}
47
+ type UserId = string;
48
+
49
+ // Constants: SCREAMING_SNAKE_CASE or camelCase
50
+ const MAX_RETRY_ATTEMPTS = 3;
51
+ const defaultTimeout = 30000; // also acceptable
52
+
53
+ // React components: PascalCase
54
+ function UserCard({ user }: UserCardProps) {}
55
+ const ProfileHeader: React.FC<Props> = () => {};
56
+
57
+ // Boolean variables: is/has/should prefix
58
+ const isActive = true;
59
+ const hasPermission = false;
60
+ const shouldRefetch = true;
61
+ ```
62
+
63
+ ## TypeScript
64
+
65
+ ### Type Definitions
66
+ ```typescript
67
+ // Prefer interfaces for objects that can be extended
68
+ interface User {
69
+ id: string;
70
+ email: string;
71
+ name: string;
72
+ createdAt: Date;
73
+ }
74
+
75
+ // Use type for unions, intersections, mapped types
76
+ type UserId = string | number;
77
+ type UserWithPosts = User & { posts: Post[] };
78
+ type Readonly<T> = { readonly [K in keyof T]: T[K] };
79
+
80
+ // Avoid `any` - use `unknown` for truly unknown types
81
+ function parseJSON(json: string): unknown {
82
+ return JSON.parse(json);
83
+ }
84
+
85
+ // Use generics for reusable types
86
+ function first<T>(arr: T[]): T | undefined {
87
+ return arr[0];
88
+ }
89
+ ```
90
+
91
+ ### Strict Null Checking
92
+ ```typescript
93
+ // Always handle null/undefined explicitly
94
+ function getUser(id: string): User | null {
95
+ const user = users.get(id);
96
+ return user ?? null;
97
+ }
98
+
99
+ // Use optional chaining and nullish coalescing
100
+ const userName = user?.profile?.name ?? 'Anonymous';
101
+
102
+ // Non-null assertion only when you're certain
103
+ const element = document.getElementById('app')!;
104
+ ```
105
+
106
+ ### Enums and Constants
107
+ ```typescript
108
+ // Prefer const objects over enums for better tree-shaking
109
+ const UserRole = {
110
+ Admin: 'admin',
111
+ User: 'user',
112
+ Guest: 'guest',
113
+ } as const;
114
+
115
+ type UserRole = typeof UserRole[keyof typeof UserRole];
116
+
117
+ // If using enums, prefer string enums
118
+ enum Status {
119
+ Pending = 'pending',
120
+ Active = 'active',
121
+ Inactive = 'inactive',
122
+ }
123
+ ```
124
+
125
+ ## Functions
126
+
127
+ ```typescript
128
+ // Use arrow functions for callbacks and short functions
129
+ const doubled = numbers.map((n) => n * 2);
130
+
131
+ // Use function declarations for top-level/hoisted functions
132
+ function processUser(user: User): ProcessedUser {
133
+ // ...
134
+ }
135
+
136
+ // Default parameters over optional with fallback
137
+ function greet(name: string, greeting = 'Hello'): string {
138
+ return `${greeting}, ${name}!`;
139
+ }
140
+
141
+ // Destructure parameters for objects
142
+ function createUser({ email, name, role = 'user' }: CreateUserParams): User {
143
+ // ...
144
+ }
145
+
146
+ // Use rest parameters over arguments
147
+ function sum(...numbers: number[]): number {
148
+ return numbers.reduce((a, b) => a + b, 0);
149
+ }
150
+ ```
151
+
152
+ ## Async Code
153
+
154
+ ```typescript
155
+ // Prefer async/await over .then() chains
156
+ async function fetchUserData(userId: string): Promise<UserData> {
157
+ const user = await fetchUser(userId);
158
+ const posts = await fetchPosts(userId);
159
+ return { user, posts };
160
+ }
161
+
162
+ // Use Promise.all for concurrent operations
163
+ async function fetchAllData(userId: string): Promise<AllData> {
164
+ const [user, posts, settings] = await Promise.all([
165
+ fetchUser(userId),
166
+ fetchPosts(userId),
167
+ fetchSettings(userId),
168
+ ]);
169
+ return { user, posts, settings };
170
+ }
171
+
172
+ // Handle errors appropriately
173
+ async function safeOperation(): Promise<Result | null> {
174
+ try {
175
+ return await riskyOperation();
176
+ } catch (error) {
177
+ if (error instanceof NetworkError) {
178
+ console.error('Network error:', error.message);
179
+ return null;
180
+ }
181
+ throw error; // Re-throw unexpected errors
182
+ }
183
+ }
184
+ ```
185
+
186
+ ## React Patterns
187
+
188
+ ```typescript
189
+ // Functional components with TypeScript
190
+ interface UserCardProps {
191
+ user: User;
192
+ onEdit?: (user: User) => void;
193
+ className?: string;
194
+ }
195
+
196
+ function UserCard({ user, onEdit, className }: UserCardProps) {
197
+ return (
198
+ <div className={className}>
199
+ <h2>{user.name}</h2>
200
+ {onEdit && <button onClick={() => onEdit(user)}>Edit</button>}
201
+ </div>
202
+ );
203
+ }
204
+
205
+ // Custom hooks
206
+ function useUser(userId: string) {
207
+ const [user, setUser] = useState<User | null>(null);
208
+ const [loading, setLoading] = useState(true);
209
+ const [error, setError] = useState<Error | null>(null);
210
+
211
+ useEffect(() => {
212
+ let cancelled = false;
213
+
214
+ async function load() {
215
+ try {
216
+ const data = await fetchUser(userId);
217
+ if (!cancelled) setUser(data);
218
+ } catch (e) {
219
+ if (!cancelled) setError(e as Error);
220
+ } finally {
221
+ if (!cancelled) setLoading(false);
222
+ }
223
+ }
224
+
225
+ load();
226
+ return () => { cancelled = true; };
227
+ }, [userId]);
228
+
229
+ return { user, loading, error };
230
+ }
231
+
232
+ // Memoization
233
+ const ExpensiveComponent = memo(function ExpensiveComponent({ data }: Props) {
234
+ const processed = useMemo(() => expensiveProcess(data), [data]);
235
+ const handleClick = useCallback(() => onClick(data.id), [data.id, onClick]);
236
+
237
+ return <div onClick={handleClick}>{processed}</div>;
238
+ });
239
+ ```
240
+
241
+ ## Error Handling
242
+
243
+ ```typescript
244
+ // Custom error classes
245
+ class AppError extends Error {
246
+ constructor(
247
+ message: string,
248
+ public code: string,
249
+ public statusCode: number = 500,
250
+ ) {
251
+ super(message);
252
+ this.name = 'AppError';
253
+ }
254
+ }
255
+
256
+ class NotFoundError extends AppError {
257
+ constructor(resource: string, id: string) {
258
+ super(`${resource} with id ${id} not found`, 'NOT_FOUND', 404);
259
+ this.name = 'NotFoundError';
260
+ }
261
+ }
262
+
263
+ // Type guards for error handling
264
+ function isAppError(error: unknown): error is AppError {
265
+ return error instanceof AppError;
266
+ }
267
+
268
+ function handleError(error: unknown): Response {
269
+ if (isAppError(error)) {
270
+ return { status: error.statusCode, message: error.message };
271
+ }
272
+ console.error('Unexpected error:', error);
273
+ return { status: 500, message: 'Internal server error' };
274
+ }
275
+ ```
276
+
277
+ ## Testing
278
+
279
+ ```typescript
280
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
281
+ // or: import { jest } from '@jest/globals';
282
+
283
+ describe('UserService', () => {
284
+ let service: UserService;
285
+ let mockDb: MockDatabase;
286
+
287
+ beforeEach(() => {
288
+ mockDb = createMockDatabase();
289
+ service = new UserService(mockDb);
290
+ });
291
+
292
+ it('should fetch user by id', async () => {
293
+ mockDb.users.get.mockResolvedValue({ id: '1', name: 'Test' });
294
+
295
+ const user = await service.getUser('1');
296
+
297
+ expect(user).toEqual({ id: '1', name: 'Test' });
298
+ expect(mockDb.users.get).toHaveBeenCalledWith('1');
299
+ });
300
+
301
+ it('should throw NotFoundError for missing user', async () => {
302
+ mockDb.users.get.mockResolvedValue(null);
303
+
304
+ await expect(service.getUser('999')).rejects.toThrow(NotFoundError);
305
+ });
306
+ });
307
+
308
+ // React Testing Library
309
+ import { render, screen, fireEvent } from '@testing-library/react';
310
+
311
+ describe('UserCard', () => {
312
+ it('should display user name', () => {
313
+ render(<UserCard user={{ id: '1', name: 'John' }} />);
314
+
315
+ expect(screen.getByText('John')).toBeInTheDocument();
316
+ });
317
+
318
+ it('should call onEdit when button clicked', () => {
319
+ const onEdit = vi.fn();
320
+ render(<UserCard user={{ id: '1', name: 'John' }} onEdit={onEdit} />);
321
+
322
+ fireEvent.click(screen.getByRole('button', { name: /edit/i }));
323
+
324
+ expect(onEdit).toHaveBeenCalledWith({ id: '1', name: 'John' });
325
+ });
326
+ });
327
+ ```
328
+
329
+ ## Project Commands
330
+
331
+ Check `.claude/commands.md` for project-specific commands. Common JS/TS commands:
332
+
333
+ ```bash
334
+ # Dependencies
335
+ npm install
336
+ npm ci # Clean install for CI
337
+
338
+ # Development
339
+ npm run dev
340
+ npm run build
341
+
342
+ # Linting & Formatting
343
+ npm run lint
344
+ npm run lint -- --fix
345
+ npm run format
346
+
347
+ # Testing
348
+ npm test
349
+ npm run test:watch
350
+ npm run test:coverage
351
+
352
+ # Type checking
353
+ npm run typecheck
354
+ npx tsc --noEmit
355
+ ```