dev-booster 1.0.0 โ 1.1.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.
- package/README.md +20 -0
- package/package.json +1 -1
- package/src/index.js +224 -13
- package/template/.devbooster/rules/GUIDE.md +16 -0
- package/template/.devbooster/rules/PROTOCOL.md +11 -8
- package/template/DEVBOOSTER_INIT.md +17 -1
package/README.md
CHANGED
|
@@ -6,6 +6,12 @@
|
|
|
6
6
|
npx dev-booster
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
+
To update an existing kit installation safely:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx dev-booster --update
|
|
13
|
+
```
|
|
14
|
+
|
|
9
15
|
---
|
|
10
16
|
|
|
11
17
|
## What it does
|
|
@@ -52,6 +58,20 @@ The AI will:
|
|
|
52
58
|
|
|
53
59
|
This process only needs to run once. The `DEVBOOSTER_INIT.md` stays in your project โ if you need to re-run after a major architectural change, just ask again.
|
|
54
60
|
|
|
61
|
+
For later kit updates, use:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npx dev-booster --update
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
This refreshes:
|
|
68
|
+
- `.devbooster/boosters/`
|
|
69
|
+
- `.devbooster/hub/`
|
|
70
|
+
|
|
71
|
+
And preserves:
|
|
72
|
+
- `.devbooster/rules/`
|
|
73
|
+
- `DEVBOOSTER_INIT.md`
|
|
74
|
+
|
|
55
75
|
---
|
|
56
76
|
|
|
57
77
|
## Boosters
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from 'fs'
|
|
2
2
|
import path from 'path'
|
|
3
|
+
import readline from 'readline/promises'
|
|
3
4
|
import { fileURLToPath } from 'url'
|
|
4
5
|
|
|
5
6
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
@@ -9,6 +10,25 @@ const TEMPLATE_DIR = path.resolve(__dirname, '..', 'template')
|
|
|
9
10
|
|
|
10
11
|
// Destination: the user's current working directory (where they ran npx)
|
|
11
12
|
const TARGET_DIR = process.cwd()
|
|
13
|
+
const args = process.argv.slice(2)
|
|
14
|
+
const IDE_BRIDGE_BLOCK = [
|
|
15
|
+
'# ๐ค DEV BOOSTER โ AGENTIC KIT BOOTSTRAP',
|
|
16
|
+
'',
|
|
17
|
+
'Before any action, read `.devbooster/rules/PROTOCOL.md` for full governance rules.',
|
|
18
|
+
]
|
|
19
|
+
const IDE_BRIDGE_MARKER = '.devbooster/rules/PROTOCOL.md'
|
|
20
|
+
const IDE_BRIDGE_FALLBACK_FLAG = path.join('hub', 'flags', 'needs-ide-bridge')
|
|
21
|
+
const IDE_BRIDGE_TARGETS = [
|
|
22
|
+
'.rules',
|
|
23
|
+
'.cursorrules',
|
|
24
|
+
'.windsurfrules',
|
|
25
|
+
'.clinerules',
|
|
26
|
+
'AGENT.md',
|
|
27
|
+
'AGENTS.md',
|
|
28
|
+
'CLAUDE.md',
|
|
29
|
+
'GEMINI.md',
|
|
30
|
+
'.github/copilot-instructions.md',
|
|
31
|
+
]
|
|
12
32
|
|
|
13
33
|
function copyDir(src, dest) {
|
|
14
34
|
fs.mkdirSync(dest, { recursive: true })
|
|
@@ -27,13 +47,149 @@ function copyDir(src, dest) {
|
|
|
27
47
|
}
|
|
28
48
|
}
|
|
29
49
|
|
|
30
|
-
|
|
50
|
+
function removeDirContents(targetDir) {
|
|
51
|
+
if (!fs.existsSync(targetDir)) return
|
|
52
|
+
|
|
53
|
+
for (const entry of fs.readdirSync(targetDir, { withFileTypes: true })) {
|
|
54
|
+
const entryPath = path.join(targetDir, entry.name)
|
|
55
|
+
fs.rmSync(entryPath, { recursive: true, force: true })
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function syncDir(src, dest) {
|
|
60
|
+
fs.mkdirSync(dest, { recursive: true })
|
|
61
|
+
removeDirContents(dest)
|
|
62
|
+
copyDir(src, dest)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function isUpdateMode() {
|
|
66
|
+
return args.includes('--update') || args.includes('update')
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function ensureTrailingNewline(content) {
|
|
70
|
+
return content.endsWith('\n') ? content : `${content}\n`
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function appendUniqueLines(filePath, lines) {
|
|
74
|
+
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) {
|
|
79
|
+
return false
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const nextContent = `${normalized}${missingLines.join('\n')}\n`
|
|
83
|
+
fs.writeFileSync(filePath, nextContent)
|
|
84
|
+
return true
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function askYesNo(question, defaultYes = true) {
|
|
88
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
89
|
+
return defaultYes
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const rl = readline.createInterface({
|
|
93
|
+
input: process.stdin,
|
|
94
|
+
output: process.stdout,
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
const suffix = defaultYes ? ' (Y/n) ' : ' (y/N) '
|
|
99
|
+
const answer = (await rl.question(`${question}${suffix}`)).trim().toLowerCase()
|
|
100
|
+
|
|
101
|
+
if (!answer) return defaultYes
|
|
102
|
+
if (answer === 'y' || answer === 'yes') return true
|
|
103
|
+
if (answer === 'n' || answer === 'no') return false
|
|
104
|
+
return defaultYes
|
|
105
|
+
} finally {
|
|
106
|
+
rl.close()
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function maybeAddDevBoosterToGitignore() {
|
|
111
|
+
const shouldIgnore = await askYesNo('Add Dev Booster to your .gitignore?', true)
|
|
112
|
+
|
|
113
|
+
if (!shouldIgnore) {
|
|
114
|
+
console.log('โธ .gitignore')
|
|
115
|
+
console.log(' status: skipped by user\n')
|
|
116
|
+
return
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const gitignorePath = path.join(TARGET_DIR, '.gitignore')
|
|
120
|
+
const changed = appendUniqueLines(gitignorePath, ['.devbooster/', 'DEVBOOSTER_INIT.md'])
|
|
121
|
+
|
|
122
|
+
console.log('โธ .gitignore')
|
|
123
|
+
if (changed) {
|
|
124
|
+
console.log(' status: updated')
|
|
125
|
+
console.log(' entries: .devbooster/, DEVBOOSTER_INIT.md\n')
|
|
126
|
+
} else {
|
|
127
|
+
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
|
|
136
|
+
}
|
|
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
|
+
}
|
|
144
|
+
|
|
145
|
+
function writeIdeBridgeFallbackFlag() {
|
|
146
|
+
const flagPath = path.join(TARGET_DIR, '.devbooster', IDE_BRIDGE_FALLBACK_FLAG)
|
|
147
|
+
fs.mkdirSync(path.dirname(flagPath), { recursive: true })
|
|
148
|
+
fs.writeFileSync(flagPath, 'create AGENTS.md fallback bridge\n')
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function clearIdeBridgeFallbackFlag() {
|
|
152
|
+
const flagPath = path.join(TARGET_DIR, '.devbooster', IDE_BRIDGE_FALLBACK_FLAG)
|
|
153
|
+
if (fs.existsSync(flagPath)) {
|
|
154
|
+
fs.rmSync(flagPath, { force: true })
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function setupIdeBridgeFiles() {
|
|
159
|
+
const touchedFiles = []
|
|
160
|
+
|
|
161
|
+
for (const relativeTarget of IDE_BRIDGE_TARGETS) {
|
|
162
|
+
const targetPath = path.join(TARGET_DIR, relativeTarget)
|
|
163
|
+
if (!fs.existsSync(targetPath)) continue
|
|
164
|
+
|
|
165
|
+
appendUniqueBlock(targetPath, IDE_BRIDGE_BLOCK, IDE_BRIDGE_MARKER)
|
|
166
|
+
touchedFiles.push(relativeTarget)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
console.log('โธ IDE bridge files')
|
|
170
|
+
if (touchedFiles.length > 0) {
|
|
171
|
+
clearIdeBridgeFallbackFlag()
|
|
172
|
+
console.log(' status: bridge instructions appended where applicable')
|
|
173
|
+
console.log(` files: ${touchedFiles.join(', ')}\n`)
|
|
174
|
+
return
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
writeIdeBridgeFallbackFlag()
|
|
178
|
+
console.log(' status: no known IDE instruction file found')
|
|
179
|
+
console.log(' action: bootstrap fallback flag created for DEVBOOSTER_INIT.md\n')
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function printHeader(subtitle) {
|
|
31
183
|
console.log(`
|
|
32
184
|
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
|
|
33
185
|
โ DEV BOOSTER โ
|
|
34
|
-
โ
|
|
186
|
+
โ ${subtitle.padEnd(44)} โ
|
|
35
187
|
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
|
|
36
188
|
`)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async function runInstall() {
|
|
192
|
+
printHeader('agentic kit installer')
|
|
37
193
|
|
|
38
194
|
// 1. Copy the full .devbooster/ kit to the user's project
|
|
39
195
|
const agentSrc = path.join(TEMPLATE_DIR, '.devbooster')
|
|
@@ -41,13 +197,13 @@ export function run() {
|
|
|
41
197
|
|
|
42
198
|
if (fs.existsSync(agentDest)) {
|
|
43
199
|
console.log('โธ .devbooster/')
|
|
44
|
-
console.log(' status:
|
|
45
|
-
console.log('
|
|
46
|
-
console.log('
|
|
200
|
+
console.log(' status: already exists in this project')
|
|
201
|
+
console.log(' action: copy skipped to avoid overwrite')
|
|
202
|
+
console.log(' tip: rename or remove the folder if you want a fresh install\n')
|
|
47
203
|
} else {
|
|
48
204
|
copyDir(agentSrc, agentDest)
|
|
49
205
|
console.log('โธ .devbooster/')
|
|
50
|
-
console.log(' status:
|
|
206
|
+
console.log(' status: installed successfully\n')
|
|
51
207
|
}
|
|
52
208
|
|
|
53
209
|
// 2. Drop DEVBOOSTER_INIT.md at the root of the user's project
|
|
@@ -56,23 +212,78 @@ export function run() {
|
|
|
56
212
|
|
|
57
213
|
if (fs.existsSync(initDest)) {
|
|
58
214
|
console.log('โธ DEVBOOSTER_INIT.md')
|
|
59
|
-
console.log(' status:
|
|
60
|
-
console.log('
|
|
215
|
+
console.log(' status: already exists in this project')
|
|
216
|
+
console.log(' action: creation skipped\n')
|
|
61
217
|
} else {
|
|
62
218
|
fs.copyFileSync(initSrc, initDest)
|
|
63
219
|
console.log('โธ DEVBOOSTER_INIT.md')
|
|
64
|
-
console.log(' status:
|
|
220
|
+
console.log(' status: created at project root\n')
|
|
65
221
|
}
|
|
66
222
|
|
|
223
|
+
await maybeAddDevBoosterToGitignore()
|
|
224
|
+
setupIdeBridgeFiles()
|
|
225
|
+
|
|
67
226
|
console.log(`
|
|
68
227
|
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
|
|
69
|
-
โ
|
|
228
|
+
โ NEXT STEP โ
|
|
70
229
|
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
|
|
71
230
|
|
|
72
|
-
|
|
231
|
+
Open your AI assistant in this project and send:
|
|
73
232
|
|
|
74
|
-
"
|
|
233
|
+
"Read DEVBOOSTER_INIT.md and execute all bootstrap steps."
|
|
75
234
|
|
|
76
|
-
|
|
235
|
+
The kit will configure itself based on your project's stack.
|
|
77
236
|
`)
|
|
78
237
|
}
|
|
238
|
+
|
|
239
|
+
function runUpdate() {
|
|
240
|
+
printHeader('safe kit update')
|
|
241
|
+
|
|
242
|
+
const kitRoot = path.join(TARGET_DIR, '.devbooster')
|
|
243
|
+
const templateRoot = path.join(TEMPLATE_DIR, '.devbooster')
|
|
244
|
+
|
|
245
|
+
if (!fs.existsSync(kitRoot)) {
|
|
246
|
+
console.log('โธ .devbooster/')
|
|
247
|
+
console.log(' status: not found in this project')
|
|
248
|
+
console.log(' action: run `npx dev-booster` first to install the kit\n')
|
|
249
|
+
return
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const updateTargets = [
|
|
253
|
+
{ name: 'boosters', src: path.join(templateRoot, 'boosters'), dest: path.join(kitRoot, 'boosters') },
|
|
254
|
+
{ name: 'hub', src: path.join(templateRoot, 'hub'), dest: path.join(kitRoot, 'hub') },
|
|
255
|
+
]
|
|
256
|
+
|
|
257
|
+
for (const target of updateTargets) {
|
|
258
|
+
syncDir(target.src, target.dest)
|
|
259
|
+
console.log(`โธ .devbooster/${target.name}/`)
|
|
260
|
+
console.log(' status: updated successfully')
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
console.log('')
|
|
264
|
+
console.log('โธ rules/')
|
|
265
|
+
console.log(' status: preserved')
|
|
266
|
+
console.log(' action: no local files were overwritten')
|
|
267
|
+
console.log('')
|
|
268
|
+
console.log('โธ DEVBOOSTER_INIT.md')
|
|
269
|
+
console.log(' status: preserved')
|
|
270
|
+
console.log(' action: no local files were overwritten\n')
|
|
271
|
+
|
|
272
|
+
console.log(`
|
|
273
|
+
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
|
|
274
|
+
โ NEXT STEP โ
|
|
275
|
+
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
|
|
276
|
+
|
|
277
|
+
Review the updated kit files in your project and, if you want,
|
|
278
|
+
reopen your AI assistant to keep working with the refreshed boosters.
|
|
279
|
+
`)
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export async function run() {
|
|
283
|
+
if (isUpdateMode()) {
|
|
284
|
+
runUpdate()
|
|
285
|
+
return
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
await runInstall()
|
|
289
|
+
}
|
|
@@ -108,4 +108,20 @@ Depois da ativaรงรฃo, envie o prรณximo passo normalmente.
|
|
|
108
108
|
Exemplo:
|
|
109
109
|
"[arquivo planning.md enviado no chat]"
|
|
110
110
|
"Agora quero validar se jรก fechamos contexto suficiente para seguir para implementation."
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
๐ก COMO ATUALIZAR O KIT:
|
|
115
|
+
Se este projeto jรก tem Dev Booster instalado e vocรช quiser receber uma versรฃo mais nova do kit,
|
|
116
|
+
use no terminal:
|
|
117
|
+
|
|
118
|
+
`npx dev-booster --update`
|
|
119
|
+
|
|
120
|
+
O update:
|
|
121
|
+
- atualiza `.devbooster/boosters/`
|
|
122
|
+
- atualiza `.devbooster/hub/`
|
|
123
|
+
- preserva `.devbooster/rules/`
|
|
124
|
+
- preserva `DEVBOOSTER_INIT.md`
|
|
125
|
+
|
|
126
|
+
Isso existe para manter seguras as regras e ajustes locais do projeto.
|
|
111
127
|
```
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
# ๐ก๏ธ PROJECT PROTOCOL (GOVERNANCE โ SINGLE SOURCE OF TRUTH)
|
|
2
|
-
**Version:**
|
|
2
|
+
**Version:** 9.0 | **Focus:** Conduct, Communication, Code Quality & Booster-Guided Work.
|
|
3
3
|
|
|
4
4
|
## ๐ค 0. PERSONA & HIERARCHY
|
|
5
5
|
- **User:** Lead Developer / Project Architect.
|
|
6
6
|
- **AI:** Strict Technical Consultant / Pair-programmer. Execute only upon explicit user authorization.
|
|
7
7
|
|
|
8
8
|
## ๐๏ธ 1. ARCHITECTURAL LINKS
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **BOOSTER
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
9
|
+
- **KIT ROOT:** Use repository-relative paths from `.devbooster/`.
|
|
10
|
+
- **BOOSTER NAVIGATION:** Use `.devbooster/rules/GUIDE.md` and `.devbooster/MANIFEST.md` as the main references to understand booster usage and available guided paths.
|
|
11
|
+
- **BOOSTER-FIRST PHILOSOPHY:** Dev Booster is manual-first. Boosters are the main guided entry point for complex work.
|
|
12
|
+
- **NO AUTO-LOADING:** Do NOT automatically search for, load, or activate Personas, Skills, or Scripts from the kit just because they exist.
|
|
13
|
+
- **BOOSTER SUGGESTION:** When the task clearly benefits from a checkpoint or guided mode, suggest the most relevant Booster instead of silently routing internal assets.
|
|
14
|
+
- **ACTIVE BOOSTER RULE:** Once a Booster is manually activated, follow that Booster's contract.
|
|
15
|
+
- **PROJECT CONTEXT:** Consult `.devbooster/rules/PROJECT.md` and other local rules when they materially affect the current task.
|
|
16
|
+
- **USER PATTERNS:** Consult `.devbooster/rules/USER_PREFERENCES.md` when the task depends on established user conventions or explicit prior preferences.
|
|
14
17
|
|
|
15
18
|
## ๐ซ 2. NON-NEGOTIABLE BEHAVIORS
|
|
16
19
|
- **NO_CODE:** Discuss and validate plans BEFORE any implementation. Use the Socratic Gate.
|
|
@@ -28,8 +31,8 @@
|
|
|
28
31
|
- **STOP-BY-DEFAULT:** Discussion and validation of plans MUST happen BEFORE implementation.
|
|
29
32
|
- **CRITIQUE MODE:** Validate with architectural rigor. Do not agree for politeness.
|
|
30
33
|
- **BILINGUAL POLICY:**
|
|
31
|
-
- **Chat:**
|
|
32
|
-
- **Logs, Code, Comments, Variables:** English.
|
|
34
|
+
- **Chat:** Follow the global language configured for the active LLM/environment.
|
|
35
|
+
- **Logs, Code, Comments, Variables:** English, unless the project explicitly requires another convention.
|
|
33
36
|
|
|
34
37
|
## ๐ 5. PERSISTENCE (MEMORIALIZATION)
|
|
35
38
|
- **THE TRIGGER:** "bota na enciclopรฉdia".
|
|
@@ -31,9 +31,25 @@ The file contains a bootstrap prompt. Execute it: scan the backend/API architect
|
|
|
31
31
|
Read `.devbooster/rules/COMERCIAL.md`.
|
|
32
32
|
The file contains a bootstrap prompt. Execute it: analyze the product's business model and overwrite the file with commercial positioning documentation.
|
|
33
33
|
|
|
34
|
-
### STEP 6 โ
|
|
34
|
+
### STEP 6 โ IDE Bridge Fallback
|
|
35
|
+
The CLI already tries to locate known AI/IDE instruction files and append the Dev Booster bridge automatically.
|
|
36
|
+
|
|
37
|
+
If the file `.devbooster/hub/flags/needs-ide-bridge` exists, it means no known IDE instruction file was found during installation.
|
|
38
|
+
In that case, create `AGENTS.md` at the project root and insert the following block:
|
|
39
|
+
|
|
40
|
+
```md
|
|
41
|
+
# ๐ค DEV BOOSTER โ AGENTIC KIT BOOTSTRAP
|
|
42
|
+
|
|
43
|
+
Before any action, read `.devbooster/rules/PROTOCOL.md` for full governance rules.
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Do not duplicate the block if the file already references `.devbooster/rules/PROTOCOL.md`.
|
|
47
|
+
If `AGENTS.md` already exists, append the block at the end instead of overwriting the file.
|
|
48
|
+
|
|
49
|
+
### STEP 7 โ Confirm Completion
|
|
35
50
|
After all files have been overwritten, report back to the user with:
|
|
36
51
|
- A summary of what was detected in each domain (project, frontend, backend, commercial).
|
|
52
|
+
- Whether the IDE bridge was already handled by the CLI or whether `AGENTS.md` had to be created as fallback.
|
|
37
53
|
- Any gaps or missing information that could not be auto-detected and may need manual input.
|
|
38
54
|
|
|
39
55
|
---
|