@ranimontagna/agent-toolkit 0.1.6 → 0.1.9

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 (108) hide show
  1. package/README.md +83 -10
  2. package/package.json +1 -1
  3. package/skills/backend/database/postgres-patterns/LICENSE.ANTIGRAVITY +21 -0
  4. package/skills/backend/database/postgres-patterns/LICENSE.ECC +21 -0
  5. package/skills/backend/database/postgres-patterns/NOTICE.md +11 -0
  6. package/skills/backend/database/postgres-patterns/SKILL.md +180 -0
  7. package/skills/backend/go/golang-patterns/LICENSE +21 -0
  8. package/skills/backend/go/golang-patterns/NOTICE.md +10 -0
  9. package/skills/backend/go/golang-patterns/SKILL.md +674 -0
  10. package/skills/backend/go/golang-testing/LICENSE +21 -0
  11. package/skills/backend/go/golang-testing/NOTICE.md +10 -0
  12. package/skills/backend/go/golang-testing/SKILL.md +329 -0
  13. package/skills/backend/java/java-coding-standards/LICENSE +21 -0
  14. package/skills/backend/java/java-coding-standards/NOTICE.md +10 -0
  15. package/skills/backend/java/java-coding-standards/SKILL.md +383 -0
  16. package/skills/backend/java/java-junit/LICENSE +21 -0
  17. package/skills/backend/java/java-junit/NOTICE.md +10 -0
  18. package/skills/backend/java/java-junit/SKILL.md +64 -0
  19. package/skills/backend/kotlin/kotlin-patterns/LICENSE +21 -0
  20. package/skills/backend/kotlin/kotlin-patterns/NOTICE.md +7 -0
  21. package/skills/backend/kotlin/kotlin-patterns/SKILL.md +711 -0
  22. package/skills/backend/kotlin/kotlin-testing/LICENSE +21 -0
  23. package/skills/backend/kotlin/kotlin-testing/NOTICE.md +7 -0
  24. package/skills/backend/kotlin/kotlin-testing/SKILL.md +824 -0
  25. package/skills/backend/python/python-patterns/LICENSE +21 -0
  26. package/skills/backend/python/python-patterns/NOTICE.md +7 -0
  27. package/skills/backend/python/python-patterns/SKILL.md +424 -0
  28. package/skills/backend/python/python-testing/LICENSE +21 -0
  29. package/skills/backend/python/python-testing/NOTICE.md +7 -0
  30. package/skills/backend/python/python-testing/SKILL.md +494 -0
  31. package/skills/devops/docker-patterns/LICENSE.ANTIGRAVITY +21 -0
  32. package/skills/devops/docker-patterns/LICENSE.ECC +21 -0
  33. package/skills/devops/docker-patterns/NOTICE.md +11 -0
  34. package/skills/devops/docker-patterns/SKILL.md +397 -0
  35. package/skills/frontend/accessibility/LICENSE +21 -0
  36. package/skills/frontend/accessibility/NOTICE.md +10 -0
  37. package/skills/frontend/accessibility/SKILL.md +145 -0
  38. package/skills/frontend/design/ui-ux-pro-max/LICENSE +21 -0
  39. package/skills/frontend/design/ui-ux-pro-max/NOTICE.md +12 -0
  40. package/skills/frontend/design/ui-ux-pro-max/SKILL.md +672 -0
  41. package/skills/frontend/design/ui-ux-pro-max/data/_sync_all.py +414 -0
  42. package/skills/frontend/design/ui-ux-pro-max/data/app-interface.csv +31 -0
  43. package/skills/frontend/design/ui-ux-pro-max/data/charts.csv +26 -0
  44. package/skills/frontend/design/ui-ux-pro-max/data/colors.csv +162 -0
  45. package/skills/frontend/design/ui-ux-pro-max/data/design.csv +1776 -0
  46. package/skills/frontend/design/ui-ux-pro-max/data/draft.csv +1779 -0
  47. package/skills/frontend/design/ui-ux-pro-max/data/google-fonts.csv +1924 -0
  48. package/skills/frontend/design/ui-ux-pro-max/data/icons.csv +106 -0
  49. package/skills/frontend/design/ui-ux-pro-max/data/landing.csv +35 -0
  50. package/skills/frontend/design/ui-ux-pro-max/data/products.csv +162 -0
  51. package/skills/frontend/design/ui-ux-pro-max/data/react-performance.csv +45 -0
  52. package/skills/frontend/design/ui-ux-pro-max/data/stacks/angular.csv +51 -0
  53. package/skills/frontend/design/ui-ux-pro-max/data/stacks/astro.csv +54 -0
  54. package/skills/frontend/design/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  55. package/skills/frontend/design/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  56. package/skills/frontend/design/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  57. package/skills/frontend/design/ui-ux-pro-max/data/stacks/laravel.csv +51 -0
  58. package/skills/frontend/design/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  59. package/skills/frontend/design/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  60. package/skills/frontend/design/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  61. package/skills/frontend/design/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  62. package/skills/frontend/design/ui-ux-pro-max/data/stacks/react.csv +54 -0
  63. package/skills/frontend/design/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  64. package/skills/frontend/design/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  65. package/skills/frontend/design/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  66. package/skills/frontend/design/ui-ux-pro-max/data/stacks/threejs.csv +54 -0
  67. package/skills/frontend/design/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  68. package/skills/frontend/design/ui-ux-pro-max/data/styles.csv +85 -0
  69. package/skills/frontend/design/ui-ux-pro-max/data/typography.csv +74 -0
  70. package/skills/frontend/design/ui-ux-pro-max/data/ui-reasoning.csv +162 -0
  71. package/skills/frontend/design/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  72. package/skills/frontend/design/ui-ux-pro-max/scripts/core.py +262 -0
  73. package/skills/frontend/design/ui-ux-pro-max/scripts/design_system.py +1148 -0
  74. package/skills/frontend/design/ui-ux-pro-max/scripts/search.py +114 -0
  75. package/skills/frontend/react/react-patterns/SKILL.md +4 -4
  76. package/skills/frontend/react/react-patterns/rules/react/LICENSE +21 -0
  77. package/skills/frontend/react/react-patterns/rules/react/NOTICE.md +11 -0
  78. package/skills/frontend/react/react-patterns/rules/react/coding-style.md +109 -0
  79. package/skills/frontend/react/react-patterns/rules/react/hooks.md +187 -0
  80. package/skills/frontend/react/react-patterns/rules/react/patterns.md +194 -0
  81. package/skills/frontend/react/react-patterns/rules/react/security.md +180 -0
  82. package/skills/frontend/react/react-patterns/rules/react/testing.md +208 -0
  83. package/skills/frontend/react/react-performance/SKILL.md +2 -2
  84. package/skills/frontend/react/react-performance/rules/react/LICENSE +21 -0
  85. package/skills/frontend/react/react-performance/rules/react/NOTICE.md +11 -0
  86. package/skills/frontend/react/react-performance/rules/react/coding-style.md +109 -0
  87. package/skills/frontend/react/react-performance/rules/react/hooks.md +187 -0
  88. package/skills/frontend/react/react-performance/rules/react/patterns.md +194 -0
  89. package/skills/frontend/react/react-performance/rules/react/security.md +180 -0
  90. package/skills/frontend/react/react-performance/rules/react/testing.md +208 -0
  91. package/skills/frontend/react/react-testing/SKILL.md +4 -4
  92. package/skills/frontend/react/react-testing/rules/react/LICENSE +21 -0
  93. package/skills/frontend/react/react-testing/rules/react/NOTICE.md +11 -0
  94. package/skills/frontend/react/react-testing/rules/react/coding-style.md +109 -0
  95. package/skills/frontend/react/react-testing/rules/react/hooks.md +187 -0
  96. package/skills/frontend/react/react-testing/rules/react/patterns.md +194 -0
  97. package/skills/frontend/react/react-testing/rules/react/security.md +180 -0
  98. package/skills/frontend/react/react-testing/rules/react/testing.md +208 -0
  99. package/skills/general/code-reviewer/AGENTS.md +292 -0
  100. package/skills/general/code-reviewer/LICENSE +201 -0
  101. package/skills/general/code-reviewer/NOTICE.md +10 -0
  102. package/skills/general/code-reviewer/SKILL.md +132 -0
  103. package/skills/general/code-reviewer/rules/correctness-error-handling.md +279 -0
  104. package/skills/general/code-reviewer/rules/maintainability-naming.md +149 -0
  105. package/skills/general/code-reviewer/rules/maintainability-type-hints.md +93 -0
  106. package/skills/general/code-reviewer/rules/performance-n-plus-one.md +250 -0
  107. package/skills/general/code-reviewer/rules/security-sql-injection.md +142 -0
  108. package/skills/general/code-reviewer/rules/security-xss-prevention.md +225 -0
@@ -0,0 +1,279 @@
1
+ ---
2
+ title: Proper Error Handling
3
+ impact: HIGH
4
+ category: correctness
5
+ tags: errors, exceptions, reliability
6
+ ---
7
+
8
+ # Proper Error Handling
9
+
10
+ Always handle errors explicitly. Don't use bare except clauses or ignore errors silently. Provide helpful error messages.
11
+
12
+ ## Why This Matters
13
+
14
+ Proper error handling:
15
+ - Prevents silent failures
16
+ - Aids debugging with clear messages
17
+ - Allows graceful degradation
18
+ - Improves user experience
19
+ - Enables error monitoring/alerting
20
+
21
+ ## ❌ Incorrect
22
+
23
+ ### Bare Except Clause
24
+ ```python
25
+ # ❌ Catches everything, including KeyboardInterrupt, SystemExit
26
+ try:
27
+ result = risky_operation()
28
+ except:
29
+ pass # Silent failure, no idea what went wrong
30
+ ```
31
+
32
+ ### Generic Exception Without Context
33
+ ```python
34
+ # ❌ Too generic, loses error information
35
+ try:
36
+ data = fetch_user(user_id)
37
+ process(data)
38
+ save_result()
39
+ except Exception:
40
+ print("Error occurred") # Which operation failed? Why?
41
+ ```
42
+
43
+ ### Ignoring Specific Errors
44
+ ```python
45
+ # ❌ Ignoring errors entirely
46
+ try:
47
+ config = json.loads(config_file.read())
48
+ except json.JSONDecodeError:
49
+ pass # App continues with undefined 'config'
50
+ ```
51
+
52
+ ## ✅ Correct
53
+
54
+ ### Catch Specific Exceptions
55
+ ```python
56
+ # ✅ Handle specific errors appropriately
57
+ try:
58
+ config = json.loads(config_file.read())
59
+ except json.JSONDecodeError as e:
60
+ logger.error(f"Invalid JSON in config file: {e}")
61
+ # Provide sensible default
62
+ config = get_default_config()
63
+ except FileNotFoundError:
64
+ logger.warning("Config file not found, using defaults")
65
+ config = get_default_config()
66
+ ```
67
+
68
+ ### Provide Context in Error Messages
69
+ ```python
70
+ # ✅ Clear, actionable error messages
71
+ def get_user(user_id: int) -> User:
72
+ try:
73
+ response = requests.get(f"{API_URL}/users/{user_id}", timeout=5)
74
+ response.raise_for_status()
75
+ return User(**response.json())
76
+ except requests.Timeout:
77
+ raise ValueError(
78
+ f"Timeout fetching user {user_id} from {API_URL}. "
79
+ "Check network connection or increase timeout."
80
+ )
81
+ except requests.HTTPError as e:
82
+ if e.response.status_code == 404:
83
+ raise UserNotFoundError(f"User {user_id} does not exist")
84
+ raise ValueError(f"HTTP error fetching user {user_id}: {e}")
85
+ except json.JSONDecodeError:
86
+ raise ValueError(f"Invalid JSON response for user {user_id}")
87
+ ```
88
+
89
+ ### Re-raise with Context
90
+ ```python
91
+ # ✅ Add context while preserving stack trace
92
+ try:
93
+ process_batch(items)
94
+ except ValidationError as e:
95
+ # Add context and re-raise
96
+ raise ValidationError(
97
+ f"Batch processing failed for {len(items)} items: {e}"
98
+ ) from e
99
+ ```
100
+
101
+ ## JavaScript/TypeScript
102
+
103
+ ### ❌ Catching Without Specificity
104
+ ```javascript
105
+ // ❌ No error handling
106
+ async function fetchUser(id) {
107
+ const response = await fetch(`/api/users/${id}`);
108
+ return response.json(); // What if fetch fails? What if not JSON?
109
+ }
110
+
111
+ // ❌ Generic catch
112
+ try {
113
+ const user = await fetchUser(id);
114
+ } catch (error) {
115
+ console.log('Error'); // Which error? From where?
116
+ }
117
+ ```
118
+
119
+ ### ✅ Explicit Error Handling
120
+ ```typescript
121
+ // ✅ Proper error handling with types
122
+ class UserNotFoundError extends Error {
123
+ constructor(userId: string) {
124
+ super(`User ${userId} not found`);
125
+ this.name = 'UserNotFoundError';
126
+ }
127
+ }
128
+
129
+ async function fetchUser(id: string): Promise<User> {
130
+ let response: Response;
131
+
132
+ try {
133
+ response = await fetch(`/api/users/${id}`, {
134
+ signal: AbortSignal.timeout(5000)
135
+ });
136
+ } catch (error) {
137
+ if (error instanceof DOMException && error.name === 'TimeoutError') {
138
+ throw new Error(`Timeout fetching user ${id}`);
139
+ }
140
+ throw new Error(`Network error fetching user ${id}: ${error}`);
141
+ }
142
+
143
+ if (!response.ok) {
144
+ if (response.status === 404) {
145
+ throw new UserNotFoundError(id);
146
+ }
147
+ throw new Error(`HTTP ${response.status} fetching user ${id}`);
148
+ }
149
+
150
+ try {
151
+ return await response.json();
152
+ } catch (error) {
153
+ throw new Error(`Invalid JSON response for user ${id}`);
154
+ }
155
+ }
156
+
157
+ // Usage
158
+ try {
159
+ const user = await fetchUser(userId);
160
+ displayUser(user);
161
+ } catch (error) {
162
+ if (error instanceof UserNotFoundError) {
163
+ showNotFoundMessage();
164
+ } else {
165
+ logger.error('Failed to load user:', error);
166
+ showErrorMessage('Unable to load user. Please try again.');
167
+ }
168
+ }
169
+ ```
170
+
171
+ ## Error Handling Patterns
172
+
173
+ ### Result Type (Rust-inspired)
174
+ ```typescript
175
+ type Result<T, E = Error> =
176
+ | { ok: true; value: T }
177
+ | { ok: false; error: E };
178
+
179
+ function parseConfig(json: string): Result<Config> {
180
+ try {
181
+ const config = JSON.parse(json);
182
+ return { ok: true, value: config };
183
+ } catch (error) {
184
+ return { ok: false, error: new Error(`Invalid config: ${error}`) };
185
+ }
186
+ }
187
+
188
+ // Usage
189
+ const result = parseConfig(configString);
190
+ if (result.ok) {
191
+ useConfig(result.value);
192
+ } else {
193
+ logger.error(result.error);
194
+ useDefaultConfig();
195
+ }
196
+ ```
197
+
198
+ ### Custom Error Classes
199
+ ```python
200
+ class DatabaseError(Exception):
201
+ """Base class for database errors."""
202
+ pass
203
+
204
+ class ConnectionError(DatabaseError):
205
+ """Database connection failed."""
206
+ pass
207
+
208
+ class QueryError(DatabaseError):
209
+ """Query execution failed."""
210
+ def __init__(self, query: str, original_error: Exception):
211
+ self.query = query
212
+ self.original_error = original_error
213
+ super().__init__(f"Query failed: {query[:100]}... Error: {original_error}")
214
+
215
+ # Usage
216
+ try:
217
+ db.execute(query)
218
+ except psycopg2.OperationalError as e:
219
+ raise ConnectionError(f"Cannot connect to database: {e}") from e
220
+ except psycopg2.Error as e:
221
+ raise QueryError(query, e) from e
222
+ ```
223
+
224
+ ## Logging Errors
225
+
226
+ ```python
227
+ import logging
228
+
229
+ logger = logging.getLogger(__name__)
230
+
231
+ try:
232
+ result = complex_operation()
233
+ except ValueError as e:
234
+ logger.error(
235
+ "Operation failed",
236
+ exc_info=True, # Include stack trace
237
+ extra={
238
+ 'user_id': user_id,
239
+ 'operation': 'complex_operation',
240
+ 'input_data': sanitized_data
241
+ }
242
+ )
243
+ raise
244
+ ```
245
+
246
+ ## Best Practices
247
+
248
+ - [ ] **Catch specific exceptions** (not bare `except` or generic `Exception`)
249
+ - [ ] **Provide context** in error messages (what failed, why, how to fix)
250
+ - [ ] **Log errors** with relevant details
251
+ - [ ] **Don't silently ignore errors**
252
+ - [ ] **Use custom exception classes** for domain errors
253
+ - [ ] **Include stack traces** in logs (but not user-facing messages)
254
+ - [ ] **Handle errors at appropriate level** (don't catch too early)
255
+ - [ ] **Clean up resources** (use context managers/try-finally)
256
+
257
+ ## Monitoring & Alerting
258
+
259
+ ```python
260
+ # Integration with error tracking
261
+ import sentry_sdk
262
+
263
+ try:
264
+ process_payment(order)
265
+ except PaymentError as e:
266
+ sentry_sdk.capture_exception(e)
267
+ sentry_sdk.set_context("order", {
268
+ "order_id": order.id,
269
+ "amount": order.total,
270
+ "user_id": order.user_id
271
+ })
272
+ raise
273
+ ```
274
+
275
+ ## References
276
+
277
+ - [Python Exception Handling Best Practices](https://docs.python.org/3/tutorial/errors.html)
278
+ - [Error Handling in JavaScript](https://javascript.info/try-catch)
279
+ - [Sentry Error Monitoring](https://sentry.io/)
@@ -0,0 +1,149 @@
1
+ ---
2
+ title: Use Meaningful Variable Names
3
+ impact: MEDIUM
4
+ category: maintainability
5
+ tags: naming, readability, code-quality
6
+ ---
7
+
8
+ # Use Meaningful Variable Names
9
+
10
+ Choose descriptive, intention-revealing names. Avoid single letters (except loop counters), abbreviations, and generic names.
11
+
12
+ ## Why This Matters
13
+
14
+ Code is read 10x more than it's written. Clear names:
15
+ - Make code self-documenting
16
+ - Reduce cognitive load
17
+ - Prevent bugs from misunderstanding
18
+ - Enable easier refactoring
19
+
20
+ ## ❌ Incorrect
21
+
22
+ ```python
23
+ # ❌ Cryptic, meaningless
24
+ def calc(x, y, z):
25
+ tmp = x * y
26
+ res = tmp + z
27
+ return res
28
+
29
+ # ❌ Too generic
30
+ data = fetch_data()
31
+ result = process(data)
32
+ output = format(result)
33
+
34
+ # ❌ Confusing abbreviations
35
+ usr_nm = input()
36
+ acc_bal = get_bal(usr_nm)
37
+ ```
38
+
39
+ ## ✅ Correct
40
+
41
+ ```python
42
+ # ✅ Clear, descriptive
43
+ def calculate_total_price(item_price: float, quantity: int, tax_rate: float) -> float:
44
+ """Calculate total price including tax."""
45
+ subtotal = item_price * quantity
46
+ total_with_tax = subtotal + (subtotal * tax_rate)
47
+ return total_with_tax
48
+
49
+ # ✅ Intention-revealing
50
+ customer_orders = fetch_customer_orders(customer_id)
51
+ validated_orders = validate_orders(customer_orders)
52
+ order_confirmation_email = format_confirmation_email(validated_orders)
53
+
54
+ # ✅ Full words
55
+ username = input("Enter username: ")
56
+ account_balance = get_account_balance(username)
57
+ ```
58
+
59
+ ## Naming Conventions by Language
60
+
61
+ ### Python (PEP 8)
62
+ ```python
63
+ # Variables & functions: snake_case
64
+ user_count = 10
65
+ def calculate_average(): pass
66
+
67
+ # Classes: PascalCase
68
+ class UserAccount: pass
69
+
70
+ # Constants: UPPER_SNAKE_CASE
71
+ MAX_RETRY_ATTEMPTS = 3
72
+ ```
73
+
74
+ ### JavaScript/TypeScript
75
+ ```javascript
76
+ // Variables & functions: camelCase
77
+ const userCount = 10;
78
+ function calculateAverage() {}
79
+
80
+ // Classes: PascalCase
81
+ class UserAccount {}
82
+
83
+ // Constants: UPPER_SNAKE_CASE or camelCase
84
+ const MAX_RETRY_ATTEMPTS = 3;
85
+ const maxRetryAttempts = 3; // Also acceptable
86
+ ```
87
+
88
+ ### Booleans
89
+ ```python
90
+ # Use is_, has_, can_ prefixes
91
+ is_active = True
92
+ has_permission = check_permission()
93
+ can_edit = user.role == "admin"
94
+
95
+ # Not: active, permission, editable
96
+ ```
97
+
98
+ ## Context Matters
99
+
100
+ ### Loop Variables
101
+ ```python
102
+ # ❌ Generic in complex loop
103
+ for i in users:
104
+ for j in i.orders:
105
+ process(j)
106
+
107
+ # ✅ Descriptive
108
+ for user in users:
109
+ for order in user.orders:
110
+ process_order(order)
111
+
112
+ # ✅ Single letter OK for simple index
113
+ for i in range(10):
114
+ print(i)
115
+ ```
116
+
117
+ ### Scope-Appropriate Names
118
+ ```python
119
+ # Short scope: concise OK
120
+ def validate(email):
121
+ # 'email' is clear in this small function
122
+ return '@' in email and '.' in email
123
+
124
+ # Long scope: more descriptive
125
+ class UserAuthenticationService:
126
+ def __init__(self):
127
+ # Longer, clearer for class-level
128
+ self.failed_login_attempts = {}
129
+ self.account_lockout_duration_seconds = 300
130
+ ```
131
+
132
+ ## Avoid Ambiguity
133
+
134
+ ```python
135
+ # ❌ Ambiguous
136
+ def get_data(id):
137
+ return data[id]
138
+
139
+ # What data? What ID?
140
+
141
+ # ✅ Specific
142
+ def get_user_by_id(user_id: int) -> User:
143
+ return users_cache[user_id]
144
+ ```
145
+
146
+ ## References
147
+
148
+ - [PEP 8 - Python Naming Conventions](https://peps.python.org/pep-0008/#naming-conventions)
149
+ - [Clean Code by Robert Martin](https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882)
@@ -0,0 +1,93 @@
1
+ ---
2
+ title: Add Type Hints
3
+ impact: MEDIUM
4
+ category: maintainability
5
+ tags: types, python, typescript, type-safety
6
+ ---
7
+
8
+ # Add Type Hints
9
+
10
+ Use type annotations to make code self-documenting and catch errors early.
11
+
12
+ ## Why This Matters
13
+
14
+ Type hints provide:
15
+ - **Static analysis** - catch bugs before runtime
16
+ - **Better IDE support** - autocomplete, refactoring
17
+ - **Documentation** - types explain intent
18
+ - **Confidence** - easier refactoring
19
+
20
+ ##❌ Incorrect
21
+
22
+ ```python
23
+ # ❌ No type hints
24
+ def get_user(id):
25
+ return users.get(id)
26
+
27
+ def process_order(order, discount):
28
+ if discount:
29
+ return order['total'] * (1 - discount)
30
+ return order['total']
31
+ ```
32
+
33
+ ## ✅ Correct
34
+
35
+ ```python
36
+ # ✅ Full type hints
37
+ from typing import Optional, Dict, Any
38
+
39
+ def get_user(id: int) -> Optional[Dict[str, Any]]:
40
+ """Fetch user by ID.
41
+
42
+ Args:
43
+ id: User ID
44
+
45
+ Returns:
46
+ User dict or None if not found
47
+ """
48
+ return users.get(id)
49
+
50
+ def process_order(order: Dict[str, Any], discount: Optional[float] = None) -> float:
51
+ """Calculate order total with optional discount.
52
+
53
+ Args:
54
+ order: Order dictionary with 'total' key
55
+ discount: Discount rate (0.0-1.0), e.g. 0.1 for 10% off
56
+
57
+ Returns:
58
+ Final price after discount
59
+ """
60
+ if discount:
61
+ return order['total'] * (1 - discount)
62
+ return order['total']
63
+ ```
64
+
65
+ ## TypeScript
66
+
67
+ ```typescript
68
+ // ✅ Explicit types
69
+ interface User {
70
+ id: number;
71
+ name: string;
72
+ email: string;
73
+ }
74
+
75
+ function getUser(id: number): User | null {
76
+ return users.get(id) ?? null;
77
+ }
78
+
79
+ function processOrder(
80
+ order: { total: number },
81
+ discount?: number
82
+ ): number {
83
+ if (discount) {
84
+ return order.total * (1 - discount);
85
+ }
86
+ return order.total;
87
+ }
88
+ ```
89
+
90
+ ## References
91
+
92
+ - [Python Type Hints](https://docs.python.org/3/library/typing.html)
93
+ - [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/intro.html)