bugcap 0.1.0 β†’ 0.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/README.md ADDED
@@ -0,0 +1,290 @@
1
+ <p align="center">
2
+ <pre align="center">
3
+ ____ _ _ ____ ____ _ ____
4
+ | __ )| | | |/ ___| / ___| / \ | _ \
5
+ | _ \| | | | | _ | | / _ \ | |_) |
6
+ | |_) | |_| | |_| | | |___ / ___ \| __/
7
+ |____/ \___/ \____| \____/_/ \_\_|
8
+ </pre>
9
+ </p>
10
+
11
+ <h3 align="center">πŸ› Transforme sua programaΓ§Γ£o com IA em um idle game no terminal</h3>
12
+
13
+ <p align="center">
14
+ <a href="#instalacao">Instalacao</a> β€’
15
+ <a href="#como-funciona">Como Funciona</a> β€’
16
+ <a href="#comandos">Comandos</a> β€’
17
+ <a href="#mecanicas">Mecanicas</a> β€’
18
+ <a href="#multi-projeto">Multi-Projeto</a>
19
+ </p>
20
+
21
+ <p align="center">
22
+ <img src="https://img.shields.io/npm/v/bugcap?color=green&label=version" alt="version" />
23
+ <img src="https://img.shields.io/badge/node-%3E%3D18-brightgreen" alt="node" />
24
+ <img src="https://img.shields.io/badge/license-MIT-blue" alt="license" />
25
+ <img src="https://img.shields.io/badge/platform-macOS%20%7C%20Linux%20%7C%20Windows-lightgrey" alt="platform" />
26
+ </p>
27
+
28
+ ---
29
+
30
+ **Bug Capitalist** e um idle game de terminal que transforma sua atividade de programacao com ferramentas de IA (Claude Code, Cursor, Copilot, Aider, etc.) em gameplay. Cada arquivo que voce modifica gera tokens, bugs e dinheiro β€” tudo sem sair do terminal.
31
+
32
+ Zero configuracao. Zero integracao. So rodar e programar.
33
+
34
+ ---
35
+
36
+ ## Por que?
37
+
38
+ Voce ja passa horas programando com IA. O Bug Capitalist gamifica isso: monitora as mudancas nos seus arquivos em tempo real e converte sua produtividade em recompensas. E um incentivo divertido pra quem vive no terminal.
39
+
40
+ ---
41
+
42
+ <h2 id="instalacao">Instalacao</h2>
43
+
44
+ ```bash
45
+ # Rodar direto sem instalar
46
+ npx bugcap
47
+
48
+ # Ou instalar globalmente
49
+ npm install -g bugcap
50
+ ```
51
+
52
+ > Requer **Node.js 18+**
53
+
54
+ ---
55
+
56
+ <h2 id="como-funciona">Como Funciona</h2>
57
+
58
+ ```
59
+ Voce programa com IA
60
+ |
61
+ v
62
+ Arquivos mudam no disco
63
+ |
64
+ v
65
+ Bug Capitalist detecta as mudancas
66
+ |
67
+ v
68
+ Tokens gerados --> XP acumulado --> Level up!
69
+ |
70
+ v
71
+ Bugs aparecem (aleatorio) --> Auto-vendidos --> $$$ no bolso
72
+ ```
73
+
74
+ O Bug Capitalist **nunca le o conteudo dos seus arquivos** β€” ele apenas observa mudancas de tamanho (linhas adicionadas/removidas). Seus dados sao somente seus.
75
+
76
+ ---
77
+
78
+ <h2 id="comandos">Comandos</h2>
79
+
80
+ ### Iniciar o jogo (watcher + interface)
81
+
82
+ ```bash
83
+ npx bugcap
84
+ ```
85
+
86
+ Abre a interface TUI interativa e comeca a monitorar o diretorio atual. Basta programar normalmente e ver os numeros subirem.
87
+
88
+ ### Monitorar um diretorio adicional (headless)
89
+
90
+ ```bash
91
+ npx bugcap watch ~/projetos/meu-app
92
+ ```
93
+
94
+ Roda em modo headless (sem interface), enviando os dados para o estado compartilhado. Perfeito para monitorar multiplos projetos simultaneamente.
95
+
96
+ ### Resetar o progresso
97
+
98
+ ```bash
99
+ npx bugcap reset # Com confirmacao
100
+ npx bugcap reset --force # Sem confirmacao
101
+ ```
102
+
103
+ ---
104
+
105
+ <h2 id="mecanicas">Mecanicas do Jogo</h2>
106
+
107
+ ### Tokens
108
+
109
+ Toda mudanca em arquivo gera tokens. A taxa base e **5 tokens por linha modificada**.
110
+
111
+ ### Bugs
112
+
113
+ Mudancas mais intensas tem chance de gerar bugs:
114
+
115
+ | Linhas modificadas | Chance de bug |
116
+ |--------------------|---------------|
117
+ | 1-49 | 15% |
118
+ | 50-99 | 25% |
119
+ | 100-149 | 35% |
120
+ | 150+ | 45% |
121
+
122
+ Bugs sao **vendidos automaticamente** assim que aparecem.
123
+
124
+ ### Dinheiro (Bug Bounty)
125
+
126
+ O preco de cada bug depende do seu level:
127
+
128
+ ```
129
+ Preco = $25 x multiplicador do level
130
+ ```
131
+
132
+ | Level | Multiplicador | Preco por Bug |
133
+ |-------|---------------|---------------|
134
+ | 1 | 1.00x | $25.00 |
135
+ | 2 | 1.25x | $31.25 |
136
+ | 5 | 2.00x | $50.00 |
137
+ | 10 | 3.25x | $81.25 |
138
+
139
+ ### XP e Levels
140
+
141
+ - Ganho: **0.1 XP por token**
142
+ - Para subir do level N para N+1, voce precisa de **N x 500 XP**
143
+ - Levels aumentam o multiplicador de venda de bugs
144
+
145
+ ---
146
+
147
+ ## Interface
148
+
149
+ ### Modo Normal (terminais >= 60 colunas)
150
+
151
+ ```
152
+ ____ _ _ ____ ____ _ ____
153
+ | __ )| | | |/ ___| / ___| / \ | _ \
154
+ | _ \| | | | | _ | | / _ \ | |_) |
155
+ | |_) | |_| | |_| | | |___ / ___ \| __/
156
+ |____/ \___/ \____| \____/_/ \_\_|
157
+
158
+ [● LIVE]
159
+
160
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
161
+ β”‚ Bug Bounty β”‚
162
+ β”‚ $1,250 β”‚
163
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
164
+
165
+ Level: 3 Bugs: 38 Tokens: 12,400
166
+
167
+ XP: [β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘] 62%
168
+
169
+ Recent Activity:
170
+ $ Bug sold β€” +$37.50 2s
171
+ πŸ› Bug detected β€” queued 2s
172
+ ⚑ 45 lines added β€” +200 tokens 5s
173
+ ```
174
+
175
+ ### Modo Compacto (terminais < 60 colunas)
176
+
177
+ ```
178
+ [●] BUG CAP $1,250 | Lv3 | T:12,400 | B:38
179
+ ```
180
+
181
+ ---
182
+
183
+ <h2 id="multi-projeto">Monitorando Multiplos Projetos</h2>
184
+
185
+ Abra terminais separados para cada projeto:
186
+
187
+ ```bash
188
+ # Terminal 1 β€” projeto principal + interface
189
+ cd ~/projetos/api && npx bugcap
190
+
191
+ # Terminal 2 β€” projeto frontend (headless)
192
+ npx bugcap watch ~/projetos/frontend
193
+
194
+ # Terminal 3 β€” projeto mobile (headless)
195
+ npx bugcap watch ~/projetos/mobile
196
+ ```
197
+
198
+ Todos os watchers escrevem no mesmo estado (`~/.bugcap/state.json`), e a interface principal reflete toda a atividade.
199
+
200
+ ---
201
+
202
+ ## Diretorios Ignorados
203
+
204
+ O watcher automaticamente ignora:
205
+
206
+ ```
207
+ .git, node_modules, vendor, dist, build,
208
+ .next, __pycache__, .venv, target
209
+ ```
210
+
211
+ Tambem respeita padroes do `.gitignore` se existir.
212
+
213
+ ---
214
+
215
+ ## Armazenamento
216
+
217
+ Os dados do jogo ficam em `~/.bugcap/`:
218
+
219
+ | Arquivo | Descricao |
220
+ |----------------|------------------------------------------------|
221
+ | `state.json` | Estado atual do jogo (tokens, bugs, level, $) |
222
+ | `events.jsonl` | Log de eventos (rotaciona automaticamente em 5MB) |
223
+
224
+ ---
225
+
226
+ ## Simulacao (para testes)
227
+
228
+ Quer testar sem programar de verdade? Use o script de simulacao:
229
+
230
+ ```bash
231
+ # Simular atividade a cada 2 segundos
232
+ sh simulate.sh /tmp/bugcap-sim 2
233
+ ```
234
+
235
+ Ele cria, modifica e deleta arquivos aleatorios, imitando um fluxo real de desenvolvimento.
236
+
237
+ ---
238
+
239
+ ## Stack
240
+
241
+ | Componente | Tecnologia |
242
+ |-------------|-------------------------------|
243
+ | Linguagem | TypeScript |
244
+ | Runtime | Node.js (v18+) |
245
+ | TUI | Ink (React para Terminal) |
246
+ | File Watcher | chokidar |
247
+ | CLI | Commander |
248
+ | Distribuicao | npm (`npx bugcap`) |
249
+
250
+ ---
251
+
252
+ ## Desenvolvimento
253
+
254
+ ```bash
255
+ # Clonar e instalar
256
+ git clone https://github.com/seu-usuario/bug-capitalist.git
257
+ cd bug-capitalist
258
+ npm install
259
+
260
+ # Modo desenvolvimento (recompila automaticamente)
261
+ npm run dev
262
+
263
+ # Build
264
+ npm run build
265
+
266
+ # Rodar
267
+ npm start
268
+ ```
269
+
270
+ ---
271
+
272
+ ## Roadmap
273
+
274
+ - [x] **v0.1** β€” MVP: watcher, TUI, economia basica, persistencia
275
+ - [ ] **v0.2** β€” Eventos dinamicos, historico, notificacoes de milestone
276
+ - [ ] **v0.3** β€” Sistema de upgrades, multiplicadores, desafios por level
277
+ - [ ] **v0.4** β€” ASCII art avancado, temas, animacoes
278
+ - [ ] **v1.0** β€” Achievements, leaderboard, hooks para Claude Code, UI multi-projeto
279
+
280
+ ---
281
+
282
+ ## Licenca
283
+
284
+ MIT
285
+
286
+ ---
287
+
288
+ <p align="center">
289
+ <strong>Pare de apenas programar. Lucre com seus bugs. πŸ›πŸ’°</strong>
290
+ </p>
@@ -30,14 +30,28 @@ function timeAgo(timestamp) {
30
30
  return `${hours}h`;
31
31
  }
32
32
  // ── ASCII Art ────────────────────────────────────────────
33
- const LOGO_LINES = [
34
- " ____ _ _ ____ ____ _ ____ ",
35
- "| __ )| | | |/ ___| / ___| / \\ | _ \\ ",
36
- "| _ \\| | | | | _ | | / _ \\ | |_) |",
37
- "| |_) | |_| | |_| | | |___ / ___ \\| __/ ",
38
- "|____/ \\___/ \\____| \\____/_/ \\_\\_| ",
33
+ const LOGO_BUG = [
34
+ " ____ _ _ ____ ",
35
+ "| __ )| | | |/ ___|",
36
+ "| _ \\| | | | | _ ",
37
+ "| |_) | |_| | |_| |",
38
+ "|____/ \\___/ \\____|",
39
39
  ];
40
- const LOGO_COLORS = [
40
+ const LOGO_CAPITALIST = [
41
+ " ____ _ ____ ___ _____ _ _ ___ ____ _____ ",
42
+ " / ___| / \\ | _ \\_ _|_ _|/ \\ | | |_ _/ ___|_ _|",
43
+ "| | / _ \\ | |_) | | | | / _ \\ | | | |\\___ \\ | | ",
44
+ "| |___ / ___ \\| __/| | | |/ ___ \\| |___ | | ___) || | ",
45
+ " \\____/_/ \\_\\_| |___| |_/_/ \\_\\_____|___|____/ |_| ",
46
+ ];
47
+ const LOGO_BUG_COLORS = [
48
+ "green",
49
+ "green",
50
+ "cyan",
51
+ "cyan",
52
+ "yellow",
53
+ ];
54
+ const LOGO_CAPITALIST_COLORS = [
41
55
  "green",
42
56
  "green",
43
57
  "cyan",
@@ -99,7 +113,7 @@ function EventLine({ event, showTime = false, }) {
99
113
  function WelcomeScreen() {
100
114
  const frame = useAnimationFrame(2);
101
115
  const bugFrame = frame % 2 === 0 ? MINI_BUG : "~(O.O)~";
102
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { flexDirection: "column", marginBottom: 1, children: LOGO_LINES.map((line, i) => (_jsx(Text, { color: LOGO_COLORS[i], children: line }, i))) }), _jsxs(Box, { borderStyle: "round", borderColor: "cyan", flexDirection: "column", paddingX: 2, paddingY: 1, children: [_jsxs(Text, { children: [_jsx(Text, { color: "yellow", children: bugFrame }), _jsx(Text, { children: " Watching for changes... Start coding!" })] }), _jsx(Text, { children: " " }), _jsx(Text, { dimColor: true, children: "Your AI coding activity will appear here." }), _jsx(Text, { dimColor: true, children: "Watch extra projects: npx bugcap watch ~/other-project" })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, italic: true, children: "Turn your AI coding into a terminal idle game" }) })] }));
116
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [LOGO_BUG.map((line, i) => (_jsx(Text, { color: LOGO_BUG_COLORS[i], children: line }, `b${i}`))), LOGO_CAPITALIST.map((line, i) => (_jsx(Text, { color: LOGO_CAPITALIST_COLORS[i], children: line }, `c${i}`)))] }), _jsxs(Box, { borderStyle: "round", borderColor: "cyan", flexDirection: "column", paddingX: 2, paddingY: 1, children: [_jsxs(Text, { children: [_jsx(Text, { color: "yellow", children: bugFrame }), _jsx(Text, { children: " Watching for changes... Start coding!" })] }), _jsx(Text, { children: " " }), _jsx(Text, { dimColor: true, children: "Your AI coding activity will appear here." }), _jsx(Text, { dimColor: true, children: "Watch extra projects: npx bugcap watch ~/other-project" })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, italic: true, children: "Turn your AI coding into a terminal idle game" }) })] }));
103
117
  }
104
118
  // ── Compact View ─────────────────────────────────────────
105
119
  function CompactView({ state, isOnline, }) {
@@ -123,7 +137,7 @@ function NormalView({ state, events, isOnline, }) {
123
137
  const moneyFlash = recentMoney && frame % 2 === 0;
124
138
  // Activity dots
125
139
  const dots = isOnline ? SPINNER_FRAMES[frame % SPINNER_FRAMES.length] : "";
126
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { flexDirection: "row", justifyContent: "space-between", children: _jsx(Box, { children: LOGO_LINES.map((line, i) => (_jsx(Text, { color: LOGO_COLORS[i], children: i === 0 ? line : "\n" + line }, i))) }) }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { children: [_jsxs(Text, { color: pulseColor, bold: true, children: ["[", pulse, "]"] }), _jsxs(Text, { color: pulseColor, bold: true, children: [" ", statusText] }), _jsx(Text, { dimColor: true, children: dots })] }) }), _jsx(Box, { borderStyle: "round", borderColor: moneyFlash ? "green" : "yellow", paddingX: 2, marginTop: 1, children: _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { dimColor: true, children: "Bug Bounty" }), _jsxs(Text, { bold: true, color: moneyFlash ? "green" : "yellow", children: [" ", "$", formatNumber(state.money)] })] }) }), _jsxs(Box, { marginTop: 1, flexDirection: "row", children: [_jsx(StatBox, { label: "Level", value: `${state.level} (${multiplier.toFixed(2)}x)`, color: "cyan" }), _jsx(StatBox, { label: "Bugs Sold", value: formatNumber(state.bugsSold), color: "red" }), _jsx(StatBox, { label: "Tokens", value: formatNumber(state.tokens), color: "green" })] }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "XP " }), _jsxs(Text, { children: [formatNumber(xpProgress), "/", formatNumber(xpNeeded)] })] }), _jsx(ProgressBar, { current: xpProgress, max: xpNeeded, width: 30, filledColor: "cyan" })] }), events.length > 0 && (_jsxs(Box, { flexDirection: "column", marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 1, children: [_jsxs(Text, { bold: true, dimColor: true, children: [" ", "Recent Activity", " "] }), events.map((event, i) => (_jsx(EventLine, { event: event, showTime: i === events.length - 1 }, i)))] })), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, italic: true, children: [MINI_BUG, " Keep coding to earn more!"] }) })] }));
140
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Box, { flexDirection: "column", children: [LOGO_BUG.map((line, i) => (_jsx(Text, { color: LOGO_BUG_COLORS[i], children: line }, `b${i}`))), LOGO_CAPITALIST.map((line, i) => (_jsx(Text, { color: LOGO_CAPITALIST_COLORS[i], children: line }, `c${i}`)))] }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { children: [_jsxs(Text, { color: pulseColor, bold: true, children: ["[", pulse, "]"] }), _jsxs(Text, { color: pulseColor, bold: true, children: [" ", statusText] }), _jsx(Text, { dimColor: true, children: dots })] }) }), _jsx(Box, { borderStyle: "round", borderColor: moneyFlash ? "green" : "yellow", paddingX: 2, marginTop: 1, children: _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { dimColor: true, children: "Bug Bounty" }), _jsxs(Text, { bold: true, color: moneyFlash ? "green" : "yellow", children: [" ", "$", formatNumber(state.money)] })] }) }), _jsxs(Box, { marginTop: 1, flexDirection: "row", children: [_jsx(StatBox, { label: "Level", value: `${state.level} (${multiplier.toFixed(2)}x)`, color: "cyan" }), _jsx(StatBox, { label: "Bugs Sold", value: formatNumber(state.bugsSold), color: "red" }), _jsx(StatBox, { label: "Tokens", value: formatNumber(state.tokens), color: "green" })] }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "XP " }), _jsxs(Text, { children: [formatNumber(xpProgress), "/", formatNumber(xpNeeded)] })] }), _jsx(ProgressBar, { current: xpProgress, max: xpNeeded, width: 30, filledColor: "cyan" })] }), events.length > 0 && (_jsxs(Box, { flexDirection: "column", marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 1, children: [_jsxs(Text, { bold: true, dimColor: true, children: [" ", "Recent Activity", " "] }), events.map((event, i) => (_jsx(EventLine, { event: event, showTime: i === events.length - 1 }, i)))] })), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, italic: true, children: [MINI_BUG, " Keep coding to earn more!"] }) })] }));
127
141
  }
128
142
  // ── Main Component ───────────────────────────────────────
129
143
  export default function Game() {
package/dist/watcher.js CHANGED
@@ -54,12 +54,20 @@ function createWatcher(targetDir) {
54
54
  saveState(state);
55
55
  // Build ignore patterns
56
56
  const gitignorePatterns = loadGitignorePatterns(resolvedDir);
57
- const ignored = [
58
- ...IGNORED_DIRS.map((d) => `**/${d}/**`),
59
- ...gitignorePatterns,
60
- ];
57
+ const ignoredSet = new Set(IGNORED_DIRS);
61
58
  const watcher = watch(resolvedDir, {
62
- ignored,
59
+ ignored: (filePath) => {
60
+ const segments = filePath.split(path.sep);
61
+ if (segments.some((seg) => ignoredSet.has(seg)))
62
+ return true;
63
+ const rel = path.relative(resolvedDir, filePath);
64
+ return gitignorePatterns.some((pattern) => {
65
+ if (pattern.endsWith("/")) {
66
+ return rel.startsWith(pattern) || segments.includes(pattern.slice(0, -1));
67
+ }
68
+ return rel === pattern || segments.includes(pattern);
69
+ });
70
+ },
63
71
  persistent: true,
64
72
  ignoreInitial: true,
65
73
  awaitWriteFinish: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bugcap",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Turn your AI coding into a terminal idle game",
5
5
  "type": "module",
6
6
  "bin": {
@@ -12,7 +12,13 @@
12
12
  "start": "node dist/cli.js",
13
13
  "prepublishOnly": "npm run build"
14
14
  },
15
- "keywords": ["cli", "terminal", "idle-game", "ai", "developer-tools"],
15
+ "keywords": [
16
+ "cli",
17
+ "terminal",
18
+ "idle-game",
19
+ "ai",
20
+ "developer-tools"
21
+ ],
16
22
  "license": "MIT",
17
23
  "files": [
18
24
  "dist"