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
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
|
|
79
|
+
function appendUniqueBlock(filePath, blockLines, marker) {
|
|
74
80
|
const existing = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : ''
|
|
75
|
-
|
|
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
|
|
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 =
|
|
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.
|