symfonia-ai-tools 1.0.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 (74) hide show
  1. package/README.md +489 -0
  2. package/bin/cli.mjs +35 -0
  3. package/lib/installer.mjs +495 -0
  4. package/lib/questions.mjs +332 -0
  5. package/lib/ui.mjs +76 -0
  6. package/lib/utils.mjs +231 -0
  7. package/package.json +26 -0
  8. package/templates/base/CLAUDE.md +34 -0
  9. package/templates/base/_ai/_guidelines_header.md +70 -0
  10. package/templates/base/_ai/context/README.md +20 -0
  11. package/templates/base/_ai/prompts/codereview.prompt.md +324 -0
  12. package/templates/base/_ai/prompts/duplicate-code-analysis.prompt.md +128 -0
  13. package/templates/base/_ai/prompts/figma-analysis.prompt.md +155 -0
  14. package/templates/base/_ai/prompts/security-review.prompt.md +46 -0
  15. package/templates/base/_ai/skills/README.md +80 -0
  16. package/templates/base/_ai/skills/TEMPLATE.md +106 -0
  17. package/templates/base/_ai/skills/babysit-prs/SKILL.md +105 -0
  18. package/templates/base/_ai/skills/debug/SKILL.md +93 -0
  19. package/templates/base/_ai/skills/fill-worklogs/SKILL.md +158 -0
  20. package/templates/base/_ai/skills/hotfix/SKILL.md +52 -0
  21. package/templates/base/_ai/skills/jira-task/SKILL.md +170 -0
  22. package/templates/base/_ai/skills/my-prs/SKILL.md +78 -0
  23. package/templates/base/_ai/skills/pr-dashboard/SKILL.md +43 -0
  24. package/templates/base/_ai/skills/pr-prepare/SKILL.md +106 -0
  25. package/templates/base/_ai/skills/refactor/SKILL.md +87 -0
  26. package/templates/base/_ai/skills/write-tests/SKILL.md +109 -0
  27. package/templates/base/_claude/settings.local.json +37 -0
  28. package/templates/base/_cursor/rules/global.mdc +7 -0
  29. package/templates/base/_editorconfig +18 -0
  30. package/templates/base/_gemini/settings.json +3 -0
  31. package/templates/base/_github/copilot-instructions.md +1 -0
  32. package/templates/base/_github/pull_request_template.md +23 -0
  33. package/templates/base/_gitignore +22 -0
  34. package/templates/base/_junie/guidelines.md +1 -0
  35. package/templates/base/commit-instructions.md +92 -0
  36. package/templates/packs/docker/_ai/instructions/docker.instructions.md +193 -0
  37. package/templates/packs/docker/_guidelines.md +10 -0
  38. package/templates/packs/docker/pack.json +8 -0
  39. package/templates/packs/laravel/_ai/instructions/api-resource.instructions.md +251 -0
  40. package/templates/packs/laravel/_ai/instructions/module.instructions.md +133 -0
  41. package/templates/packs/laravel/_ai/instructions/service-repository.instructions.md +215 -0
  42. package/templates/packs/laravel/_ai/instructions/testing.instructions.md +278 -0
  43. package/templates/packs/laravel/_ai/skills/migration/SKILL.md +172 -0
  44. package/templates/packs/laravel/_ai/skills/new-endpoint/SKILL.md +165 -0
  45. package/templates/packs/laravel/_ai/skills/new-module/SKILL.md +208 -0
  46. package/templates/packs/laravel/_ai/skills/queued-job/SKILL.md +248 -0
  47. package/templates/packs/laravel/_ai/skills/testing-feature/SKILL.md +196 -0
  48. package/templates/packs/laravel/_ai/skills/testing-manual/SKILL.md +186 -0
  49. package/templates/packs/laravel/_ai/skills/testing-unit/SKILL.md +200 -0
  50. package/templates/packs/laravel/_guidelines.md +25 -0
  51. package/templates/packs/laravel/pack.json +6 -0
  52. package/templates/packs/playwright/_ai/instructions/playwright.instructions.md +219 -0
  53. package/templates/packs/playwright/_ai/skills/playwright/README.md +194 -0
  54. package/templates/packs/playwright/_ai/skills/playwright/SKILL.md +1245 -0
  55. package/templates/packs/playwright/_ai/skills/playwright-codereview/SKILL.md +642 -0
  56. package/templates/packs/playwright/_ai/skills/playwright-record/README.md +87 -0
  57. package/templates/packs/playwright/_ai/skills/playwright-record/SKILL.md +564 -0
  58. package/templates/packs/playwright/_guidelines.md +12 -0
  59. package/templates/packs/playwright/pack.json +9 -0
  60. package/templates/packs/storybook/_ai/instructions/storybook.instructions.md +181 -0
  61. package/templates/packs/storybook/pack.json +6 -0
  62. package/templates/packs/vitest/_ai/instructions/vitest.instructions.md +688 -0
  63. package/templates/packs/vitest/pack.json +6 -0
  64. package/templates/packs/vue3/_ai/instructions/api.instructions.md +163 -0
  65. package/templates/packs/vue3/_ai/instructions/coding-conventions.instructions.md +160 -0
  66. package/templates/packs/vue3/_ai/instructions/composables.instructions.md +218 -0
  67. package/templates/packs/vue3/_ai/instructions/forms.instructions.md +227 -0
  68. package/templates/packs/vue3/_ai/instructions/store.instructions.md +504 -0
  69. package/templates/packs/vue3/_ai/instructions/vue.instructions.md +339 -0
  70. package/templates/packs/vue3/_ai/skills/api-integration/SKILL.md +195 -0
  71. package/templates/packs/vue3/_ai/skills/new-component/SKILL.md +133 -0
  72. package/templates/packs/vue3/_ai/skills/new-module/SKILL.md +177 -0
  73. package/templates/packs/vue3/_guidelines.md +45 -0
  74. package/templates/packs/vue3/pack.json +11 -0
@@ -0,0 +1,227 @@
1
+ ---
2
+ applyTo: "**/*Form*.vue,**/*form*.ts,**/validation*"
3
+ ---
4
+
5
+ # Forms & Validation - Instrukcje
6
+
7
+ ## Walidacja - funkcje bazowe
8
+
9
+ Trzymaj funkcje walidacji w `utils/validation.ts`:
10
+
11
+ ```typescript
12
+ // utils/validation.ts
13
+ export function isNotEmpty(value: unknown): boolean {
14
+ if (value === null || value === undefined) return false;
15
+ if (typeof value === 'string') return value.trim().length > 0;
16
+ if (Array.isArray(value)) return value.length > 0;
17
+ return true;
18
+ }
19
+
20
+ export function isValidEmail(value: string): boolean {
21
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
22
+ }
23
+
24
+ export function isValidPhone(value: string): boolean {
25
+ return /^\+?[\d\s-()]{7,15}$/.test(value);
26
+ }
27
+
28
+ export function isValidUrl(value: string): boolean {
29
+ try {
30
+ new URL(value);
31
+ return true;
32
+ } catch {
33
+ return false;
34
+ }
35
+ }
36
+
37
+ export function isValidLength(value: string, min: number, max?: number): boolean {
38
+ const len = value.trim().length;
39
+ if (len < min) return false;
40
+ if (max !== undefined && len > max) return false;
41
+ return true;
42
+ }
43
+
44
+ export function isValidZipCode(value: string): boolean {
45
+ return /^\d{2}-\d{3}$/.test(value);
46
+ }
47
+ ```
48
+
49
+ ## ValidationBuilder (fluent API)
50
+
51
+ Do walidacji zlozonych obiektow:
52
+
53
+ ```typescript
54
+ // utils/validation-builder.ts
55
+ interface IValidationResult {
56
+ isValid: boolean;
57
+ errors: string[];
58
+ }
59
+
60
+ class ValidationBuilder<T> {
61
+ private entity: T;
62
+ private errors: string[] = [];
63
+
64
+ constructor(entity: T) {
65
+ this.entity = entity;
66
+ }
67
+
68
+ validateString(getValue: (e: T) => string, fieldName: string, min = 1, max?: number): this {
69
+ const val = getValue(this.entity);
70
+ if (!val || val.trim().length < min) {
71
+ this.errors.push(`${fieldName} jest wymagane (min. ${min} znakow)`);
72
+ } else if (max && val.trim().length > max) {
73
+ this.errors.push(`${fieldName} max ${max} znakow`);
74
+ }
75
+ return this;
76
+ }
77
+
78
+ validatePositiveInteger(getValue: (e: T) => number, fieldName: string): this {
79
+ const val = getValue(this.entity);
80
+ if (!Number.isInteger(val) || val <= 0) {
81
+ this.errors.push(`${fieldName} musi byc liczba dodatnia`);
82
+ }
83
+ return this;
84
+ }
85
+
86
+ validateEnum<E>(getValue: (e: T) => E, allowed: E[], fieldName: string): this {
87
+ if (!allowed.includes(getValue(this.entity))) {
88
+ this.errors.push(`${fieldName} ma niedozwolona wartosc`);
89
+ }
90
+ return this;
91
+ }
92
+
93
+ validateCustom(condition: (e: T) => boolean, errorMessage: string): this {
94
+ if (!condition(this.entity)) {
95
+ this.errors.push(errorMessage);
96
+ }
97
+ return this;
98
+ }
99
+
100
+ validateNested(result: IValidationResult): this {
101
+ this.errors.push(...result.errors);
102
+ return this;
103
+ }
104
+
105
+ build(): IValidationResult {
106
+ return { isValid: this.errors.length === 0, errors: this.errors };
107
+ }
108
+ }
109
+
110
+ export function createValidator<T>(entity: T): ValidationBuilder<T> {
111
+ return new ValidationBuilder(entity);
112
+ }
113
+ ```
114
+
115
+ ### Uzycie
116
+
117
+ ```typescript
118
+ const result = createValidator(user)
119
+ .validatePositiveInteger(u => u.id, 'ID')
120
+ .validateString(u => u.name, 'Imie', 2, 50)
121
+ .validateString(u => u.email, 'Email', 5, 255)
122
+ .validateCustom(u => isValidEmail(u.email), 'Nieprawidlowy format email')
123
+ .validateEnum(u => u.role, ['admin', 'user', 'guest'], 'Rola')
124
+ .build();
125
+
126
+ if (!result.isValid) {
127
+ // result.errors: ['Email: Nieprawidlowy format email', ...]
128
+ }
129
+ ```
130
+
131
+ ## Walidacja w komponencie Vue
132
+
133
+ ```vue
134
+ <script setup lang="ts">
135
+ import { reactive, computed } from 'vue';
136
+ import { isNotEmpty, isValidEmail, isValidLength } from '@/utils/validation';
137
+
138
+ interface IFormData {
139
+ name: string;
140
+ email: string;
141
+ description: string;
142
+ }
143
+
144
+ const form = reactive<IFormData>({
145
+ name: '',
146
+ email: '',
147
+ description: '',
148
+ });
149
+
150
+ const validationErrors = computed(() => {
151
+ const errors: Record<string, string> = {};
152
+
153
+ if (!isNotEmpty(form.name)) errors.name = 'Nazwa jest wymagana';
154
+ else if (!isValidLength(form.name, 2, 100)) errors.name = 'Nazwa: 2-100 znakow';
155
+
156
+ if (!isNotEmpty(form.email)) errors.email = 'Email jest wymagany';
157
+ else if (!isValidEmail(form.email)) errors.email = 'Nieprawidlowy email';
158
+
159
+ if (form.description && !isValidLength(form.description, 0, 1000)) {
160
+ errors.description = 'Opis: max 1000 znakow';
161
+ }
162
+
163
+ return errors;
164
+ });
165
+
166
+ const isFormValid = computed(() => Object.keys(validationErrors.value).length === 0);
167
+ </script>
168
+
169
+ <template>
170
+ <form @submit.prevent="onSubmit">
171
+ <div class="form-field" :class="{ 'has-error': validationErrors.name }">
172
+ <label>Nazwa</label>
173
+ <input v-model="form.name" data-testid="formNameInput" />
174
+ <span v-if="validationErrors.name" class="error">{{ validationErrors.name }}</span>
175
+ </div>
176
+
177
+ <div class="form-field" :class="{ 'has-error': validationErrors.email }">
178
+ <label>Email</label>
179
+ <input v-model="form.email" type="email" data-testid="formEmailInput" />
180
+ <span v-if="validationErrors.email" class="error">{{ validationErrors.email }}</span>
181
+ </div>
182
+
183
+ <button type="submit" :disabled="!isFormValid" data-testid="formSubmitButton">
184
+ Zapisz
185
+ </button>
186
+ </form>
187
+ </template>
188
+ ```
189
+
190
+ ## Obsluga bledow z API (422)
191
+
192
+ ```typescript
193
+ const serverErrors = ref<Record<string, string[]>>({});
194
+
195
+ async function onSubmit() {
196
+ serverErrors.value = {};
197
+ try {
198
+ await FeatureService.create(form);
199
+ notify('success', 'Zapisano');
200
+ } catch (error) {
201
+ if (error instanceof AxiosError && error.response?.status === 422) {
202
+ serverErrors.value = error.response.data.errors;
203
+ } else {
204
+ printError(error);
205
+ }
206
+ }
207
+ }
208
+ ```
209
+
210
+ ## Composable do formularzy
211
+
212
+ Wydziel logike formularza do composable (patrz: `composables.instructions.md`):
213
+
214
+ ```typescript
215
+ const { form, errors, submitting, submitForm, resetForm } = useFeatureForm(itemId);
216
+ ```
217
+
218
+ ## Zasady
219
+
220
+ 1. **Walidacja client-side** - computed `validationErrors`, nie metody
221
+ 2. **Walidacja server-side** - obsluz 422 i pokaz bledy przy polach
222
+ 3. **Funkcje walidacji** - reuzywalne, w `utils/validation.ts`
223
+ 4. **ValidationBuilder** - dla zlozonych obiektow (nie dla formularzy UI)
224
+ 5. **`data-testid`** - na kazdym input i button formularza
225
+ 6. **Disable submit** - gdy `!isFormValid` lub `submitting`
226
+ 7. **Reset** - czysc formularz po sukcesie lub przy anulowaniu
227
+ 8. **Nie waliduj pustych opcjonalnych pol** - sprawdzaj tylko jesli wartosc istnieje