autoworkflow 3.1.5 → 3.5.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 (123) hide show
  1. package/.claude/commands/analyze.md +19 -0
  2. package/.claude/commands/audit.md +26 -0
  3. package/.claude/commands/build.md +39 -0
  4. package/.claude/commands/commit.md +25 -0
  5. package/.claude/commands/fix.md +23 -0
  6. package/.claude/commands/plan.md +18 -0
  7. package/.claude/commands/suggest.md +23 -0
  8. package/.claude/commands/verify.md +18 -0
  9. package/.claude/hooks/post-bash-router.sh +20 -0
  10. package/.claude/hooks/post-commit.sh +140 -0
  11. package/.claude/hooks/pre-edit.sh +129 -0
  12. package/.claude/hooks/session-check.sh +79 -0
  13. package/.claude/settings.json +40 -6
  14. package/.claude/settings.local.json +3 -1
  15. package/.claude/skills/actix.md +337 -0
  16. package/.claude/skills/alembic.md +504 -0
  17. package/.claude/skills/angular.md +237 -0
  18. package/.claude/skills/api-design.md +187 -0
  19. package/.claude/skills/aspnet-core.md +377 -0
  20. package/.claude/skills/astro.md +245 -0
  21. package/.claude/skills/auth-clerk.md +327 -0
  22. package/.claude/skills/auth-firebase.md +367 -0
  23. package/.claude/skills/auth-nextauth.md +359 -0
  24. package/.claude/skills/auth-supabase.md +368 -0
  25. package/.claude/skills/axum.md +386 -0
  26. package/.claude/skills/blazor.md +456 -0
  27. package/.claude/skills/chi.md +348 -0
  28. package/.claude/skills/code-review.md +133 -0
  29. package/.claude/skills/csharp.md +296 -0
  30. package/.claude/skills/css-modules.md +325 -0
  31. package/.claude/skills/cypress.md +343 -0
  32. package/.claude/skills/debugging.md +133 -0
  33. package/.claude/skills/diesel.md +392 -0
  34. package/.claude/skills/django.md +301 -0
  35. package/.claude/skills/docker.md +319 -0
  36. package/.claude/skills/doctrine.md +473 -0
  37. package/.claude/skills/documentation.md +182 -0
  38. package/.claude/skills/dotnet.md +409 -0
  39. package/.claude/skills/drizzle.md +293 -0
  40. package/.claude/skills/echo.md +321 -0
  41. package/.claude/skills/eloquent.md +256 -0
  42. package/.claude/skills/emotion.md +426 -0
  43. package/.claude/skills/entity-framework.md +370 -0
  44. package/.claude/skills/express.md +316 -0
  45. package/.claude/skills/fastapi.md +329 -0
  46. package/.claude/skills/fastify.md +299 -0
  47. package/.claude/skills/fiber.md +315 -0
  48. package/.claude/skills/flask.md +322 -0
  49. package/.claude/skills/gin.md +342 -0
  50. package/.claude/skills/git.md +116 -0
  51. package/.claude/skills/github-actions.md +353 -0
  52. package/.claude/skills/go.md +377 -0
  53. package/.claude/skills/gorm.md +409 -0
  54. package/.claude/skills/graphql.md +478 -0
  55. package/.claude/skills/hibernate.md +379 -0
  56. package/.claude/skills/hono.md +306 -0
  57. package/.claude/skills/java.md +400 -0
  58. package/.claude/skills/jest.md +313 -0
  59. package/.claude/skills/jpa.md +282 -0
  60. package/.claude/skills/kotlin.md +347 -0
  61. package/.claude/skills/kubernetes.md +363 -0
  62. package/.claude/skills/laravel.md +414 -0
  63. package/.claude/skills/mcp-browser.md +320 -0
  64. package/.claude/skills/mcp-database.md +219 -0
  65. package/.claude/skills/mcp-fetch.md +241 -0
  66. package/.claude/skills/mcp-filesystem.md +204 -0
  67. package/.claude/skills/mcp-github.md +217 -0
  68. package/.claude/skills/mcp-memory.md +240 -0
  69. package/.claude/skills/mcp-search.md +218 -0
  70. package/.claude/skills/mcp-slack.md +262 -0
  71. package/.claude/skills/micronaut.md +388 -0
  72. package/.claude/skills/mongodb.md +319 -0
  73. package/.claude/skills/mongoose.md +355 -0
  74. package/.claude/skills/mysql.md +281 -0
  75. package/.claude/skills/nestjs.md +335 -0
  76. package/.claude/skills/nextjs-app-router.md +260 -0
  77. package/.claude/skills/nextjs-pages.md +172 -0
  78. package/.claude/skills/nuxt.md +202 -0
  79. package/.claude/skills/openapi.md +489 -0
  80. package/.claude/skills/performance.md +199 -0
  81. package/.claude/skills/php.md +398 -0
  82. package/.claude/skills/playwright.md +371 -0
  83. package/.claude/skills/postgresql.md +257 -0
  84. package/.claude/skills/prisma.md +293 -0
  85. package/.claude/skills/pydantic.md +304 -0
  86. package/.claude/skills/pytest.md +313 -0
  87. package/.claude/skills/python.md +272 -0
  88. package/.claude/skills/quarkus.md +377 -0
  89. package/.claude/skills/react.md +230 -0
  90. package/.claude/skills/redis.md +391 -0
  91. package/.claude/skills/refactoring.md +143 -0
  92. package/.claude/skills/remix.md +246 -0
  93. package/.claude/skills/rest-api.md +490 -0
  94. package/.claude/skills/rocket.md +366 -0
  95. package/.claude/skills/rust.md +341 -0
  96. package/.claude/skills/sass.md +380 -0
  97. package/.claude/skills/sea-orm.md +382 -0
  98. package/.claude/skills/security.md +167 -0
  99. package/.claude/skills/sequelize.md +395 -0
  100. package/.claude/skills/spring-boot.md +416 -0
  101. package/.claude/skills/sqlalchemy.md +269 -0
  102. package/.claude/skills/sqlx-rust.md +408 -0
  103. package/.claude/skills/state-jotai.md +346 -0
  104. package/.claude/skills/state-mobx.md +353 -0
  105. package/.claude/skills/state-pinia.md +431 -0
  106. package/.claude/skills/state-redux.md +337 -0
  107. package/.claude/skills/state-tanstack-query.md +434 -0
  108. package/.claude/skills/state-zustand.md +340 -0
  109. package/.claude/skills/styled-components.md +403 -0
  110. package/.claude/skills/svelte.md +238 -0
  111. package/.claude/skills/sveltekit.md +207 -0
  112. package/.claude/skills/symfony.md +437 -0
  113. package/.claude/skills/tailwind.md +279 -0
  114. package/.claude/skills/terraform.md +394 -0
  115. package/.claude/skills/testing-library.md +371 -0
  116. package/.claude/skills/trpc.md +426 -0
  117. package/.claude/skills/typeorm.md +368 -0
  118. package/.claude/skills/vitest.md +330 -0
  119. package/.claude/skills/vue.md +202 -0
  120. package/.claude/skills/warp.md +365 -0
  121. package/README.md +135 -52
  122. package/package.json +1 -1
  123. package/system/triggers.md +152 -11
@@ -0,0 +1,456 @@
1
+ # Blazor Skill
2
+
3
+ ## Component with Parameters
4
+ \`\`\`razor
5
+ @page "/users/{Id}"
6
+ @inject IUserService UserService
7
+ @inject NavigationManager Navigation
8
+
9
+ <PageTitle>User Details</PageTitle>
10
+
11
+ @if (_loading)
12
+ {
13
+ <LoadingSpinner />
14
+ }
15
+ else if (_user is null)
16
+ {
17
+ <div class="alert alert-danger">User not found</div>
18
+ }
19
+ else
20
+ {
21
+ <div class="card">
22
+ <h1>@_user.Name</h1>
23
+ <p>@_user.Email</p>
24
+ <Badge IsActive="@_user.IsActive" />
25
+ <button class="btn btn-primary" @onclick="HandleEdit">Edit</button>
26
+ </div>
27
+ }
28
+
29
+ @code {
30
+ [Parameter]
31
+ public string Id { get; set; } = null!;
32
+
33
+ [Parameter]
34
+ public EventCallback<User> OnUserUpdated { get; set; }
35
+
36
+ private User? _user;
37
+ private bool _loading = true;
38
+
39
+ protected override async Task OnInitializedAsync()
40
+ {
41
+ await LoadUser();
42
+ }
43
+
44
+ protected override async Task OnParametersSetAsync()
45
+ {
46
+ // Called when parameters change (e.g., route changes)
47
+ await LoadUser();
48
+ }
49
+
50
+ private async Task LoadUser()
51
+ {
52
+ _loading = true;
53
+ try
54
+ {
55
+ _user = await UserService.GetByIdAsync(Id);
56
+ }
57
+ finally
58
+ {
59
+ _loading = false;
60
+ }
61
+ }
62
+
63
+ private void HandleEdit()
64
+ {
65
+ Navigation.NavigateTo($"/users/{Id}/edit");
66
+ }
67
+ }
68
+ \`\`\`
69
+
70
+ ## Forms with Validation
71
+ \`\`\`razor
72
+ @page "/users/create"
73
+ @inject IUserService UserService
74
+ @inject NavigationManager Navigation
75
+
76
+ <h1>Create User</h1>
77
+
78
+ <EditForm Model="@_model" OnValidSubmit="HandleSubmit">
79
+ <DataAnnotationsValidator />
80
+ <ValidationSummary class="text-danger" />
81
+
82
+ <div class="mb-3">
83
+ <label class="form-label">Email</label>
84
+ <InputText @bind-Value="_model.Email" class="form-control" />
85
+ <ValidationMessage For="@(() => _model.Email)" class="text-danger" />
86
+ </div>
87
+
88
+ <div class="mb-3">
89
+ <label class="form-label">Name</label>
90
+ <InputText @bind-Value="_model.Name" class="form-control" />
91
+ <ValidationMessage For="@(() => _model.Name)" class="text-danger" />
92
+ </div>
93
+
94
+ <div class="mb-3">
95
+ <label class="form-label">Role</label>
96
+ <InputSelect @bind-Value="_model.Role" class="form-select">
97
+ <option value="">Select a role...</option>
98
+ @foreach (var role in _roles)
99
+ {
100
+ <option value="@role">@role</option>
101
+ }
102
+ </InputSelect>
103
+ </div>
104
+
105
+ <div class="mb-3">
106
+ <label class="form-label">Active</label>
107
+ <InputCheckbox @bind-Value="_model.IsActive" class="form-check-input" />
108
+ </div>
109
+
110
+ <button type="submit" class="btn btn-primary" disabled="@_submitting">
111
+ @if (_submitting)
112
+ {
113
+ <span class="spinner-border spinner-border-sm"></span>
114
+ }
115
+ Create User
116
+ </button>
117
+
118
+ @if (_error is not null)
119
+ {
120
+ <div class="alert alert-danger mt-3">@_error</div>
121
+ }
122
+ </EditForm>
123
+
124
+ @code {
125
+ private CreateUserModel _model = new();
126
+ private bool _submitting;
127
+ private string? _error;
128
+ private readonly string[] _roles = ["User", "Admin", "Moderator"];
129
+
130
+ private async Task HandleSubmit()
131
+ {
132
+ _submitting = true;
133
+ _error = null;
134
+
135
+ try
136
+ {
137
+ var user = await UserService.CreateAsync(_model);
138
+ Navigation.NavigateTo($"/users/{user.Id}");
139
+ }
140
+ catch (Exception ex)
141
+ {
142
+ _error = ex.Message;
143
+ }
144
+ finally
145
+ {
146
+ _submitting = false;
147
+ }
148
+ }
149
+
150
+ public class CreateUserModel
151
+ {
152
+ [Required, EmailAddress, MaxLength(255)]
153
+ public string Email { get; set; } = "";
154
+
155
+ [Required, MinLength(2), MaxLength(100)]
156
+ public string Name { get; set; } = "";
157
+
158
+ [Required]
159
+ public string Role { get; set; } = "";
160
+
161
+ public bool IsActive { get; set; } = true;
162
+ }
163
+ }
164
+ \`\`\`
165
+
166
+ ## Component Communication
167
+ \`\`\`razor
168
+ // Parent Component
169
+ @page "/users"
170
+
171
+ <UserList Users="_users" OnUserSelected="HandleUserSelected" />
172
+
173
+ @if (_selectedUser is not null)
174
+ {
175
+ <UserDetails User="_selectedUser" OnDelete="HandleDelete" />
176
+ }
177
+
178
+ @code {
179
+ private List<User> _users = new();
180
+ private User? _selectedUser;
181
+
182
+ protected override async Task OnInitializedAsync()
183
+ {
184
+ _users = await UserService.GetAllAsync();
185
+ }
186
+
187
+ private void HandleUserSelected(User user)
188
+ {
189
+ _selectedUser = user;
190
+ }
191
+
192
+ private async Task HandleDelete(User user)
193
+ {
194
+ await UserService.DeleteAsync(user.Id);
195
+ _users.Remove(user);
196
+ _selectedUser = null;
197
+ }
198
+ }
199
+
200
+ // Child Component - UserList.razor
201
+ <ul class="list-group">
202
+ @foreach (var user in Users)
203
+ {
204
+ <li class="list-group-item @(user == SelectedUser ? "active" : "")"
205
+ @onclick="() => OnUserSelected.InvokeAsync(user)">
206
+ @user.Name
207
+ </li>
208
+ }
209
+ </ul>
210
+
211
+ @code {
212
+ [Parameter, EditorRequired]
213
+ public List<User> Users { get; set; } = null!;
214
+
215
+ [Parameter]
216
+ public User? SelectedUser { get; set; }
217
+
218
+ [Parameter]
219
+ public EventCallback<User> OnUserSelected { get; set; }
220
+ }
221
+
222
+ // Child Component - UserDetails.razor
223
+ <div class="card">
224
+ <h3>@User.Name</h3>
225
+ <button class="btn btn-danger" @onclick="HandleDelete">Delete</button>
226
+ </div>
227
+
228
+ @code {
229
+ [Parameter, EditorRequired]
230
+ public User User { get; set; } = null!;
231
+
232
+ [Parameter]
233
+ public EventCallback<User> OnDelete { get; set; }
234
+
235
+ private async Task HandleDelete()
236
+ {
237
+ await OnDelete.InvokeAsync(User);
238
+ }
239
+ }
240
+ \`\`\`
241
+
242
+ ## State Management with Cascading Values
243
+ \`\`\`razor
244
+ // App.razor or layout
245
+ <CascadingValue Value="_authState">
246
+ <Router AppAssembly="@typeof(App).Assembly">
247
+ <!-- ... -->
248
+ </Router>
249
+ </CascadingValue>
250
+
251
+ @code {
252
+ private AuthState _authState = new();
253
+ }
254
+
255
+ // Consuming component
256
+ @code {
257
+ [CascadingParameter]
258
+ public AuthState Auth { get; set; } = null!;
259
+
260
+ private bool IsAuthenticated => Auth.User is not null;
261
+ }
262
+
263
+ // State container service (for complex state)
264
+ public class AppState
265
+ {
266
+ public User? CurrentUser { get; private set; }
267
+ public event Action? OnChange;
268
+
269
+ public void SetUser(User user)
270
+ {
271
+ CurrentUser = user;
272
+ NotifyStateChanged();
273
+ }
274
+
275
+ public void ClearUser()
276
+ {
277
+ CurrentUser = null;
278
+ NotifyStateChanged();
279
+ }
280
+
281
+ private void NotifyStateChanged() => OnChange?.Invoke();
282
+ }
283
+
284
+ // Register as scoped service
285
+ builder.Services.AddScoped<AppState>();
286
+
287
+ // Usage in component
288
+ @inject AppState State
289
+ @implements IDisposable
290
+
291
+ @code {
292
+ protected override void OnInitialized()
293
+ {
294
+ State.OnChange += StateHasChanged;
295
+ }
296
+
297
+ public void Dispose()
298
+ {
299
+ State.OnChange -= StateHasChanged;
300
+ }
301
+ }
302
+ \`\`\`
303
+
304
+ ## JavaScript Interop
305
+ \`\`\`razor
306
+ @inject IJSRuntime JS
307
+
308
+ <button @onclick="ShowAlert">Show Alert</button>
309
+ <button @onclick="CopyToClipboard">Copy</button>
310
+
311
+ <div @ref="_chartContainer"></div>
312
+
313
+ @code {
314
+ private ElementReference _chartContainer;
315
+
316
+ private async Task ShowAlert()
317
+ {
318
+ await JS.InvokeVoidAsync("alert", "Hello from Blazor!");
319
+ }
320
+
321
+ private async Task CopyToClipboard()
322
+ {
323
+ await JS.InvokeVoidAsync("navigator.clipboard.writeText", "Copied text");
324
+ }
325
+
326
+ protected override async Task OnAfterRenderAsync(bool firstRender)
327
+ {
328
+ if (firstRender)
329
+ {
330
+ // Initialize JS library after first render
331
+ await JS.InvokeVoidAsync("initChart", _chartContainer);
332
+ }
333
+ }
334
+
335
+ // Calling .NET from JS
336
+ [JSInvokable]
337
+ public static Task<string> GetDataFromDotNet()
338
+ {
339
+ return Task.FromResult("Data from .NET");
340
+ }
341
+
342
+ // Instance method
343
+ private DotNetObjectReference<MyComponent>? _dotNetRef;
344
+
345
+ protected override void OnInitialized()
346
+ {
347
+ _dotNetRef = DotNetObjectReference.Create(this);
348
+ }
349
+
350
+ [JSInvokable]
351
+ public void HandleJsCallback(string data)
352
+ {
353
+ // Handle callback from JS
354
+ StateHasChanged();
355
+ }
356
+
357
+ public void Dispose()
358
+ {
359
+ _dotNetRef?.Dispose();
360
+ }
361
+ }
362
+ \`\`\`
363
+
364
+ ## Lifecycle Methods
365
+ \`\`\`razor
366
+ @implements IAsyncDisposable
367
+
368
+ @code {
369
+ // Called once when component is initialized
370
+ protected override void OnInitialized() { }
371
+ protected override async Task OnInitializedAsync() { }
372
+
373
+ // Called when parameters are set/changed
374
+ protected override void OnParametersSet() { }
375
+ protected override async Task OnParametersSetAsync() { }
376
+
377
+ // Called after each render
378
+ protected override void OnAfterRender(bool firstRender) { }
379
+ protected override async Task OnAfterRenderAsync(bool firstRender)
380
+ {
381
+ if (firstRender)
382
+ {
383
+ // Only runs once after first render
384
+ // Good for JS interop initialization
385
+ }
386
+ }
387
+
388
+ // Control when component re-renders
389
+ protected override bool ShouldRender()
390
+ {
391
+ return _dataChanged; // Return false to skip render
392
+ }
393
+
394
+ // Cleanup
395
+ public async ValueTask DisposeAsync()
396
+ {
397
+ // Cleanup subscriptions, JS interop, etc.
398
+ }
399
+ }
400
+ \`\`\`
401
+
402
+ ## Render Fragments and Templated Components
403
+ \`\`\`razor
404
+ // DataGrid.razor - Templated component
405
+ @typeparam TItem
406
+
407
+ <table class="table">
408
+ <thead>
409
+ <tr>@HeaderTemplate</tr>
410
+ </thead>
411
+ <tbody>
412
+ @foreach (var item in Items)
413
+ {
414
+ <tr>@RowTemplate(item)</tr>
415
+ }
416
+ </tbody>
417
+ </table>
418
+
419
+ @code {
420
+ [Parameter, EditorRequired]
421
+ public List<TItem> Items { get; set; } = null!;
422
+
423
+ [Parameter, EditorRequired]
424
+ public RenderFragment HeaderTemplate { get; set; } = null!;
425
+
426
+ [Parameter, EditorRequired]
427
+ public RenderFragment<TItem> RowTemplate { get; set; } = null!;
428
+ }
429
+
430
+ // Usage
431
+ <DataGrid Items="_users">
432
+ <HeaderTemplate>
433
+ <th>Name</th>
434
+ <th>Email</th>
435
+ </HeaderTemplate>
436
+ <RowTemplate Context="user">
437
+ <td>@user.Name</td>
438
+ <td>@user.Email</td>
439
+ </RowTemplate>
440
+ </DataGrid>
441
+ \`\`\`
442
+
443
+ ## ✅ DO
444
+ - Use \`@key\` directive in loops for optimal diffing
445
+ - Use \`EventCallback<T>\` for component communication
446
+ - Use \`[EditorRequired]\` for required parameters
447
+ - Use \`OnAfterRenderAsync\` for JS interop initialization
448
+ - Dispose event handlers and JS references
449
+ - Use \`StateHasChanged()\` only when necessary
450
+
451
+ ## ❌ DON'T
452
+ - Don't call \`StateHasChanged()\` in lifecycle methods (automatic)
453
+ - Don't do heavy work in \`OnInitialized\` - use \`OnInitializedAsync\`
454
+ - Don't use \`@bind\` and \`@onchange\` on same element
455
+ - Don't forget \`@implements IDisposable\` when subscribing to events
456
+ - Don't use \`IJSRuntime\` in \`OnInitialized\` - wait for \`OnAfterRender\`