dev-booster 1.1.0 → 1.1.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dev-booster",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "Reusable AI development kit with manual boosters, governance, and project bootstrap",
5
5
  "type": "module",
6
6
  "scripts": {
package/src/index.js CHANGED
@@ -11,6 +11,12 @@ const TEMPLATE_DIR = path.resolve(__dirname, '..', 'template')
11
11
  // Destination: the user's current working directory (where they ran npx)
12
12
  const TARGET_DIR = process.cwd()
13
13
  const args = process.argv.slice(2)
14
+ const GITIGNORE_BLOCK = [
15
+ '# DEV-BOOSTER',
16
+ '.devbooster/',
17
+ 'DEVBOOSTER_INIT.md',
18
+ ]
19
+ const GITIGNORE_MARKER = '# DEV-BOOSTER'
14
20
  const IDE_BRIDGE_BLOCK = [
15
21
  '# 🤖 DEV BOOSTER — AGENTIC KIT BOOTSTRAP',
16
22
  '',
@@ -70,16 +76,16 @@ function ensureTrailingNewline(content) {
70
76
  return content.endsWith('\n') ? content : `${content}\n`
71
77
  }
72
78
 
73
- function appendUniqueLines(filePath, lines) {
79
+ function appendUniqueBlock(filePath, blockLines, marker) {
74
80
  const existing = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : ''
75
- const normalized = ensureTrailingNewline(existing)
76
- const missingLines = lines.filter((line) => !existing.includes(line))
77
-
78
- if (missingLines.length === 0) {
81
+ if (existing.includes(marker)) {
79
82
  return false
80
83
  }
81
84
 
82
- const nextContent = `${normalized}${missingLines.join('\n')}\n`
85
+ const trimmedEnd = existing.replace(/\s*$/, '')
86
+ const prefix = trimmedEnd.length > 0 ? `${trimmedEnd}\n\n` : ''
87
+ const nextContent = `${prefix}${blockLines.join('\n')}\n`
88
+ fs.mkdirSync(path.dirname(filePath), { recursive: true })
83
89
  fs.writeFileSync(filePath, nextContent)
84
90
  return true
85
91
  }
@@ -117,29 +123,16 @@ async function maybeAddDevBoosterToGitignore() {
117
123
  }
118
124
 
119
125
  const gitignorePath = path.join(TARGET_DIR, '.gitignore')
120
- const changed = appendUniqueLines(gitignorePath, ['.devbooster/', 'DEVBOOSTER_INIT.md'])
126
+ const changed = appendUniqueBlock(gitignorePath, GITIGNORE_BLOCK, GITIGNORE_MARKER)
121
127
 
122
128
  console.log('▸ .gitignore')
123
129
  if (changed) {
124
130
  console.log(' status: updated')
125
- console.log(' entries: .devbooster/, DEVBOOSTER_INIT.md\n')
131
+ console.log(' entries: # DEV-BOOSTER, .devbooster/, DEVBOOSTER_INIT.md\n')
126
132
  } else {
127
133
  console.log(' status: already configured')
128
- console.log(' entries: .devbooster/, DEVBOOSTER_INIT.md\n')
129
- }
130
- }
131
-
132
- function appendUniqueBlock(filePath, blockLines, marker) {
133
- const existing = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : ''
134
- if (existing.includes(marker)) {
135
- return false
134
+ console.log(' entries: # DEV-BOOSTER, .devbooster/, DEVBOOSTER_INIT.md\n')
136
135
  }
137
-
138
- const normalized = ensureTrailingNewline(existing)
139
- const nextContent = `${normalized}${blockLines.join('\n')}\n`
140
- fs.mkdirSync(path.dirname(filePath), { recursive: true })
141
- fs.writeFileSync(filePath, nextContent)
142
- return true
143
136
  }
144
137
 
145
138
  function writeIdeBridgeFallbackFlag() {
@@ -0,0 +1,251 @@
1
+ ---
2
+ name: react-file-organization
3
+ description: Personal React file organization style for restructuring imports, component sections, and local formatting without changing behavior.
4
+ allowed-tools: Read, Write, Edit
5
+ version: 1.0
6
+ priority: OPTIONAL
7
+ ---
8
+
9
+ # React File Organization
10
+
11
+ > **Optional personal skill** - Use this when the goal is to reorganize a React file according to a strict structural preference, without changing behavior.
12
+
13
+ ---
14
+
15
+ ## Goal
16
+
17
+ Organize a React file following the rules below.
18
+
19
+ **Do not change functionality.**
20
+ Only reorganize structure, imports, and presentation where the rules explicitly allow it.
21
+
22
+ This skill is intentionally opinionated and personal.
23
+ It is meant to make the file "feel right" for this specific organization style, not to enforce a universal best practice.
24
+
25
+ ---
26
+
27
+ ## Activation Behavior
28
+
29
+ If the user invokes this skill by name without clearly providing the target file:
30
+
31
+ - do not start reorganizing anything yet
32
+ - do not guess the file automatically
33
+ - confirm that the skill is ready
34
+ - ask which React file should be organized
35
+
36
+ Use a short response such as:
37
+
38
+ ```md
39
+ Skill `react-file-organization` loaded.
40
+
41
+ I can reorganize a React file using this personal structure style without changing behavior.
42
+
43
+ Which file should I organize?
44
+ ```
45
+
46
+ Only proceed after the user provides the target file or a clear file reference.
47
+
48
+ ---
49
+
50
+ ## Safe Operating Mode
51
+
52
+ Apply this skill only when all of the following are true:
53
+
54
+ - the target is clearly a React file (`.tsx`, `.jsx`, or a React component file)
55
+ - the file can be reorganized without changing runtime behavior
56
+ - hooks, requests, and local declarations are already at top level of the component body
57
+ - the requested change is organizational, not functional
58
+
59
+ If the file does **not** fit this structure:
60
+ - do **not** force the full pattern
61
+ - do **not** invent missing sections
62
+ - do **not** convert APIs or libraries
63
+ - do **not** move code in a way that changes execution order or semantics
64
+
65
+ If there is any real risk of behavioral change, stop and explain which part is unsafe to reorder.
66
+
67
+ ---
68
+
69
+ ## Applicability Rules
70
+
71
+ - If the file does not use `Formik`, skip the `Formik` section entirely.
72
+ - If the file does not use `React.useEffect`, do not invent one.
73
+ - If the file does not use API hooks, skip request grouping.
74
+ - If the file does not use `lucide-react`, do not replace another icon library automatically.
75
+ - If the file does not use `zustand`, do not create fake hook groupings just to fit the pattern.
76
+ - If there are no multiline imports, do not create them artificially.
77
+ - If the file already follows another stable organization style and reorganizing it would create churn without benefit, keep the file mostly as-is.
78
+
79
+ ---
80
+
81
+ ## Hard Safety Stops
82
+
83
+ Do **not** use this skill to:
84
+
85
+ - rewrite business logic
86
+ - rename functions, variables, or props unless strictly required for organization and clearly safe
87
+ - convert component style (`function` ↔ `const`)
88
+ - change hook dependencies
89
+ - move hooks across conditional logic
90
+ - move declarations in ways that can affect hoisting, closures, or side effects
91
+ - remove comments that carry important business or implementation context
92
+ - delete code unless it is clearly unused import noise or dead commented-out code with no project value
93
+
94
+ When in doubt, prefer partial organization over risky cleanup.
95
+
96
+ ---
97
+
98
+ ## 1. Import Structure
99
+
100
+ ```typescript
101
+ import React from 'react' // always first
102
+
103
+ // mandatory blank line
104
+
105
+ // default imports (without {}) - smaller → larger by the imported identifier
106
+ import Input from '@/components/commons/input'
107
+ import CpfMask from '@/masks/cpf.mask'
108
+ import useUserStore from '@/zustand/user.store'
109
+
110
+ // mandatory blank line
111
+
112
+ // named imports with {} - smaller → larger by the content inside the braces
113
+ import { api } from '@/trpc/react'
114
+ import { toast } from 'sonner'
115
+ import { Button } from '@/components/ui/button'
116
+ import { useFormik } from 'formik'
117
+ import { Eye, EyeOff, Plus } from 'lucide-react'
118
+
119
+ // mandatory blank line
120
+
121
+ // multiline imports - each block separated by a blank line
122
+ import {
123
+ Select,
124
+ SelectContent,
125
+ SelectItem,
126
+ } from '@/components/ui/select'
127
+
128
+ // mandatory blank line
129
+
130
+ import {
131
+ Dialog,
132
+ DialogContent,
133
+ } from '@/components/ui/dialog'
134
+
135
+ // mandatory blank line
136
+
137
+ // imports with * or type - always last
138
+ import * as Yup from 'yup'
139
+ ```
140
+
141
+ ---
142
+
143
+ ## 2. Internal Component Structure
144
+
145
+ ```typescript
146
+ const Component: React.FC = () => {
147
+ // 1. React.useState - larger → smaller by line length
148
+ const [showPassword, setShowPassword] = React.useState<boolean>(false)
149
+ const [loading, setLoading] = React.useState(false)
150
+
151
+ // 2. imported hook function destructuring
152
+ const { modalState, setModal } = useModalStore()
153
+ const { setLoading } = useLoadingStore()
154
+ const { dbUser } = useUserStore()
155
+
156
+ // 3. API requests
157
+ // GET requests first
158
+ const { data: users } = api.user.getAll.useQuery()
159
+ const { data: positions } = api.position.getAll.useQuery()
160
+
161
+ // mutation requests second
162
+ const { mutateAsync: createUser } = api.user.create.useMutation()
163
+
164
+ // 4. Formik
165
+ const formik = useFormik({ ... })
166
+
167
+ // 5. custom functions
168
+ const handleSubmit = React.useMemo(() => { ... }, [])
169
+
170
+ // 6. React.useEffect
171
+ React.useEffect(() => { ... }, [])
172
+
173
+ // 7. return
174
+ return (...)
175
+ }
176
+ ```
177
+
178
+ ---
179
+
180
+ ## 3. Icon Rules
181
+
182
+ - Always use `size={}` instead of sizing only with `className`
183
+ - Never place icons inside buttons for this organization style
184
+ - Always import icons from `lucide-react`
185
+
186
+ ```typescript
187
+ // correct
188
+ <Eye size={20} />
189
+
190
+ // wrong
191
+ <button><Eye className="w-5 h-5" /></button>
192
+ ```
193
+
194
+ ---
195
+
196
+ ## 4. General Rules
197
+
198
+ - Always respond in Portuguese
199
+ - Always keep spacing between import groups
200
+ - Remove unused imports when clearly safe
201
+ - Remove commented code only when it is clearly dead noise and not useful documentation
202
+ - Do not change behavior, only organize
203
+ - Follow the order even when some sections do not exist
204
+ - If a section does not exist in the file, skip it naturally
205
+ - If a rule conflicts with file safety, preserve safety first
206
+
207
+ ---
208
+
209
+ ## 5. Sorting Criteria
210
+
211
+ ### Default Imports
212
+
213
+ Count the imported identifier before `from`:
214
+
215
+ ```typescript
216
+ import Input from '@/components/commons/input'
217
+ import useModalStore from '@/zustand/modal.store'
218
+ import useLoadingStore from '@/zustand/loading.store'
219
+ ```
220
+
221
+ ### Named Imports
222
+
223
+ Count the content inside `{}`:
224
+
225
+ ```typescript
226
+ import { api } from '@/trpc/react'
227
+ import { Button } from '@/components/ui/button'
228
+ import { Eye, EyeOff } from 'lucide-react'
229
+ ```
230
+
231
+ ---
232
+
233
+ ## Execution Prompt
234
+
235
+ Use this command when applying the skill:
236
+
237
+ **"Organize this React file following exactly all rules from the prompt above. Do not change behavior, only reorganize."**
238
+
239
+ If needed, you may also use this safer variant:
240
+
241
+ **"Organize this React file using the react-file-organization skill. Apply the style only where it is safe, skip missing sections naturally, and do not change behavior."**
242
+
243
+ ---
244
+
245
+ ## Notes
246
+
247
+ - This skill is intentionally opinionated.
248
+ - It is not a global Dev Booster rule.
249
+ - It should not be auto-loaded by any booster.
250
+ - Use it only when this exact organization style is desired.
251
+ - Prefer making the user happy over forcing mechanical symmetry.