@jaguilar87/gaia-ops 3.3.1 → 3.3.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/CHANGELOG.md +39 -0
- package/hooks/README.md +117 -47
- package/hooks/pre_tool_use.py +429 -351
- package/hooks/shell_parser.py +287 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,45 @@ All notable changes to the CLAUDE.md orchestrator instructions are documented in
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [3.3.2] - 2025-12-11
|
|
9
|
+
|
|
10
|
+
### Read-Only Auto-Approval & Code Optimization
|
|
11
|
+
|
|
12
|
+
Major improvements to the permission system with compound command support and code quality optimizations.
|
|
13
|
+
|
|
14
|
+
#### Added
|
|
15
|
+
- **Compound command auto-approval**: Safe compound commands (`cat file | grep foo`, `ls && pwd`, `tail file || echo error`) now execute WITHOUT ASK prompts
|
|
16
|
+
- **Extended safe command list**: Added `base64`, `md5sum`, `sha256sum`, `tar`, `gzip`, `time`, `timeout`, `sleep` to always-safe commands
|
|
17
|
+
- **Multi-word command support**: Added `kubectl get/describe/logs`, `helm list/status`, `flux check/get`, `docker ps/images`, `gcloud/aws describe/list` as always-safe
|
|
18
|
+
|
|
19
|
+
#### Changed
|
|
20
|
+
- **R1: Unified safe command configuration** (`SAFE_COMMANDS_CONFIG`) - Single source of truth for all safe commands, eliminating ~150 lines of duplicate patterns
|
|
21
|
+
- **R2: Unified validation flow** - `classify_command_tier()` now uses `is_read_only_command()` for T0 classification
|
|
22
|
+
- **R4: Singleton ShellCommandParser** - Single instance reused across all validations
|
|
23
|
+
|
|
24
|
+
#### Removed
|
|
25
|
+
- **R3: Dead code removal** - Removed unused `_contains_command_chaining()` method (~30 lines)
|
|
26
|
+
- **Removed tenacity dependency** - Simplified capabilities loading (retry logic was over-engineering)
|
|
27
|
+
- **Removed duplicate `allowed_read_operations`** - Now derived from `SAFE_COMMANDS_CONFIG`
|
|
28
|
+
|
|
29
|
+
#### Fixed
|
|
30
|
+
- Compound commands with safe components no longer trigger ASK prompts
|
|
31
|
+
- More consistent tier classification between auto-approval and security validation
|
|
32
|
+
|
|
33
|
+
#### Technical Details
|
|
34
|
+
- **Lines reduced**: ~200 lines removed through deduplication
|
|
35
|
+
- **Maintainability**: Single source of truth for safe commands
|
|
36
|
+
- **Performance**: Singleton parser avoids repeated instantiation
|
|
37
|
+
|
|
38
|
+
#### Test Results
|
|
39
|
+
All previous tests continue to pass:
|
|
40
|
+
- Simple read-only commands: NO ASK (auto-approved)
|
|
41
|
+
- Safe compound commands: NO ASK (NEW - auto-approved)
|
|
42
|
+
- Dangerous commands: BLOCKED correctly
|
|
43
|
+
- Compound with dangerous components: BLOCKED correctly
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
8
47
|
## [3.3.1] - 2025-12-11
|
|
9
48
|
|
|
10
49
|
### Granular AWS Permissions & Command Chaining Block
|
package/hooks/README.md
CHANGED
|
@@ -37,17 +37,44 @@ Log a .claude/logs/
|
|
|
37
37
|
|
|
38
38
|
### Pre-Execution Hooks
|
|
39
39
|
|
|
40
|
-
#### `pre_tool_use.py` (~
|
|
40
|
+
#### `pre_tool_use.py` (~750 lineas)
|
|
41
41
|
El guardian principal - valida TODAS las operaciones antes de ejecutarlas.
|
|
42
42
|
|
|
43
|
+
**Caracteristicas principales (v3.3.2):**
|
|
44
|
+
|
|
45
|
+
1. **Auto-aprobacion de comandos read-only:**
|
|
46
|
+
- Comandos simples: `ls`, `cat`, `grep`, `git status` -> NO ASK
|
|
47
|
+
- Comandos compuestos seguros: `cat file | grep foo`, `ls && pwd` -> NO ASK
|
|
48
|
+
- Retorna `permissionDecision: "allow"` para bypass del ASK prompt
|
|
49
|
+
|
|
50
|
+
2. **Configuracion unificada (`SAFE_COMMANDS_CONFIG`):**
|
|
51
|
+
```python
|
|
52
|
+
SAFE_COMMANDS_CONFIG = {
|
|
53
|
+
"always_safe": {"ls", "cat", "grep", ...},
|
|
54
|
+
"always_safe_multiword": {"git status", "kubectl get", ...},
|
|
55
|
+
"conditional_safe": {"sed": [r"-i\b"], "curl": [r"-T\b"], ...}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
3. **ShellCommandParser singleton:**
|
|
60
|
+
- Parsea comandos compuestos (pipes, &&, ||, ;)
|
|
61
|
+
- Valida cada componente individualmente
|
|
62
|
+
- Si TODOS son seguros -> auto-aprueba
|
|
63
|
+
|
|
43
64
|
**Que valida:**
|
|
44
65
|
- Tier de seguridad (T0, T1, T2, T3)
|
|
45
66
|
- Permisos segun settings.json
|
|
46
67
|
- Comandos bloqueados globalmente
|
|
47
68
|
- Contexto de ejecucion
|
|
69
|
+
- Componentes de comandos compuestos
|
|
48
70
|
|
|
49
71
|
**Reglas de decision:**
|
|
50
72
|
```python
|
|
73
|
+
# 1. Auto-aprobacion para read-only
|
|
74
|
+
if is_read_only_command(command):
|
|
75
|
+
return AUTO_APPROVE # Retorna JSON con permissionDecision: "allow"
|
|
76
|
+
|
|
77
|
+
# 2. Validacion de seguridad
|
|
51
78
|
if tier == "T3" and not has_approval():
|
|
52
79
|
return BLOCK # Requiere aprobacion
|
|
53
80
|
|
|
@@ -86,6 +113,26 @@ Validacion especializada para comandos de Kubernetes.
|
|
|
86
113
|
|
|
87
114
|
---
|
|
88
115
|
|
|
116
|
+
#### `shell_parser.py` (~290 lineas)
|
|
117
|
+
Parser nativo de Python para comandos shell compuestos.
|
|
118
|
+
|
|
119
|
+
**Que hace:**
|
|
120
|
+
- Parsea pipes: `cmd1 | cmd2` -> `["cmd1", "cmd2"]`
|
|
121
|
+
- Parsea AND: `cmd1 && cmd2` -> `["cmd1", "cmd2"]`
|
|
122
|
+
- Parsea OR: `cmd1 || cmd2` -> `["cmd1", "cmd2"]`
|
|
123
|
+
- Preserva strings con comillas: `echo 'a|b'` -> `["echo 'a|b'"]`
|
|
124
|
+
|
|
125
|
+
**Uso:**
|
|
126
|
+
```python
|
|
127
|
+
from shell_parser import ShellCommandParser
|
|
128
|
+
|
|
129
|
+
parser = ShellCommandParser()
|
|
130
|
+
components = parser.parse("ls | grep foo && wc -l")
|
|
131
|
+
# ["ls", "grep foo", "wc -l"]
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
89
136
|
### Post-Execution Hooks
|
|
90
137
|
|
|
91
138
|
#### `post_tool_use.py` (~300 lineas)
|
|
@@ -138,23 +185,52 @@ Se ejecuta cuando un subagente termina su trabajo. Captura metricas y detecta an
|
|
|
138
185
|
|
|
139
186
|
---
|
|
140
187
|
|
|
141
|
-
##
|
|
188
|
+
## Auto-Aprobacion de Comandos Read-Only
|
|
142
189
|
|
|
143
|
-
###
|
|
190
|
+
### Como Funciona
|
|
144
191
|
|
|
145
|
-
Claude Code
|
|
192
|
+
Cuando Claude Code ejecuta un comando bash:
|
|
146
193
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
194
|
+
1. **Hook recibe el comando** via stdin como JSON
|
|
195
|
+
2. **Verifica si es read-only** usando `is_read_only_command()`
|
|
196
|
+
3. **Si es read-only**, retorna JSON con `permissionDecision: "allow"`
|
|
197
|
+
4. **Claude Code bypassa el ASK prompt** y ejecuta inmediatamente
|
|
198
|
+
|
|
199
|
+
### Comandos Auto-Aprobados
|
|
200
|
+
|
|
201
|
+
**Simples (siempre seguros):**
|
|
202
|
+
- System info: `uname`, `hostname`, `whoami`, `date`, `uptime`, `free`
|
|
203
|
+
- File listing: `ls`, `pwd`, `tree`, `which`, `stat`, `file`
|
|
204
|
+
- Text processing: `awk`, `cut`, `grep`, `head`, `tail`, `sort`, `wc`
|
|
205
|
+
- Network: `ping`, `dig`, `nslookup`, `netstat`, `ss`
|
|
206
|
+
- Git read-only: `git status`, `git diff`, `git log`, `git branch`
|
|
207
|
+
|
|
208
|
+
**Compuestos (si TODOS los componentes son seguros):**
|
|
209
|
+
- `cat file | grep foo` -> auto-aprueba
|
|
210
|
+
- `ls && pwd` -> auto-aprueba
|
|
211
|
+
- `tail file || echo error` -> auto-aprueba
|
|
156
212
|
|
|
157
|
-
|
|
213
|
+
**Condicionales (seguros excepto con flags peligrosos):**
|
|
214
|
+
- `sed` -> seguro excepto con `-i` (in-place edit)
|
|
215
|
+
- `curl` -> seguro excepto con `-T`, `-X POST`, `--data`
|
|
216
|
+
- `find` -> seguro excepto con `-delete`, `-exec rm`
|
|
217
|
+
|
|
218
|
+
### Comandos NO Auto-Aprobados
|
|
219
|
+
|
|
220
|
+
**Siempre bloqueados:**
|
|
221
|
+
- `rm`, `rm -rf`, `shred`
|
|
222
|
+
- `dd`, `fdisk`, `parted`
|
|
223
|
+
- `sudo`, `su`
|
|
224
|
+
- `kill -9`, `killall -9`
|
|
225
|
+
- `terraform apply`, `kubectl apply`, `git push`
|
|
226
|
+
|
|
227
|
+
**Compuestos con componentes peligrosos:**
|
|
228
|
+
- `ls && rm -rf /` -> BLOQUEADO (rm es peligroso)
|
|
229
|
+
- `cat | kubectl apply` -> BLOQUEADO (kubectl apply es peligroso)
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Configuracion de Permisos
|
|
158
234
|
|
|
159
235
|
Los hooks leen `.claude/settings.json` para decisiones:
|
|
160
236
|
|
|
@@ -177,7 +253,9 @@ Los hooks leen `.claude/settings.json` para decisiones:
|
|
|
177
253
|
}
|
|
178
254
|
```
|
|
179
255
|
|
|
180
|
-
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Logs de Auditoria
|
|
181
259
|
|
|
182
260
|
Todos los hooks escriben a `.claude/logs/`:
|
|
183
261
|
|
|
@@ -190,40 +268,25 @@ cat .claude/logs/*.jsonl | jq 'select(.tier == "T3")'
|
|
|
190
268
|
|
|
191
269
|
# Buscar operaciones bloqueadas
|
|
192
270
|
cat .claude/logs/*.jsonl | jq 'select(.action == "blocked")'
|
|
193
|
-
```
|
|
194
271
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
272
|
+
# Ver auto-aprobaciones
|
|
273
|
+
grep "AUTO-APPROVED" .claude/logs/pre_tool_use-*.log
|
|
274
|
+
```
|
|
198
275
|
|
|
199
|
-
|
|
276
|
+
---
|
|
200
277
|
|
|
201
|
-
|
|
202
|
-
def execute_hook(context: dict) -> dict:
|
|
203
|
-
"""
|
|
204
|
-
Args:
|
|
205
|
-
context: Informacion del comando/fase
|
|
206
|
-
|
|
207
|
-
Returns:
|
|
208
|
-
{
|
|
209
|
-
"action": "allow" | "block" | "ask",
|
|
210
|
-
"reason": "Explicacion",
|
|
211
|
-
"metadata": {}
|
|
212
|
-
}
|
|
213
|
-
"""
|
|
214
|
-
pass
|
|
215
|
-
```
|
|
278
|
+
## Tiers de Seguridad
|
|
216
279
|
|
|
217
|
-
|
|
280
|
+
| Tier | Tipo de Operacion | Requiere Approval | Auto-Aprueba |
|
|
281
|
+
|------|-------------------|-------------------|--------------|
|
|
282
|
+
| **T0** | Read-only (get, list) | No | Si |
|
|
283
|
+
| **T1** | Validation (validate, dry-run) | No | No |
|
|
284
|
+
| **T2** | Planning (plan, simulate) | No | No |
|
|
285
|
+
| **T3** | Execution (apply, delete) | **Si** | No |
|
|
218
286
|
|
|
219
|
-
|
|
220
|
-
|------|-------------------|-------------------|-----------------|
|
|
221
|
-
| **T0** | Read-only (get, list) | No | pre_tool_use |
|
|
222
|
-
| **T1** | Validation (validate, dry-run) | No | pre_tool_use |
|
|
223
|
-
| **T2** | Planning (plan, simulate) | No | pre_tool_use |
|
|
224
|
-
| **T3** | Execution (apply, delete) | **Si** | pre_tool_use + pre_phase |
|
|
287
|
+
---
|
|
225
288
|
|
|
226
|
-
|
|
289
|
+
## Tests de Hooks
|
|
227
290
|
|
|
228
291
|
Los hooks tienen tests de integracion:
|
|
229
292
|
|
|
@@ -233,18 +296,25 @@ python3 -m pytest tests/integration/ -v
|
|
|
233
296
|
|
|
234
297
|
# Tests especificos de hooks
|
|
235
298
|
python3 -m pytest tests/integration/test_hooks_integration.py -v
|
|
299
|
+
|
|
300
|
+
# Test manual de comandos
|
|
301
|
+
python3 .claude/hooks/pre_tool_use.py "ls -la"
|
|
302
|
+
python3 .claude/hooks/pre_tool_use.py --test
|
|
236
303
|
```
|
|
237
304
|
|
|
305
|
+
---
|
|
306
|
+
|
|
238
307
|
## Referencias
|
|
239
308
|
|
|
240
309
|
**Archivos de hooks:**
|
|
241
310
|
```
|
|
242
311
|
hooks/
|
|
243
|
-
├── pre_tool_use.py (~
|
|
312
|
+
├── pre_tool_use.py (~750 lineas) - Guardian principal + auto-approval
|
|
244
313
|
├── post_tool_use.py (~300 lineas) - Auditor principal
|
|
245
314
|
├── pre_phase_hook.py (~200 lineas) - Validador de fases
|
|
246
315
|
├── post_phase_hook.py (~150 lineas) - Auditor de fases
|
|
247
316
|
├── pre_kubectl_security.py (~180 lineas) - K8s security
|
|
317
|
+
├── shell_parser.py (~290 lineas) - Parser de comandos compuestos
|
|
248
318
|
└── subagent_stop.py (~200 lineas) - Workflow metrics
|
|
249
319
|
```
|
|
250
320
|
|
|
@@ -258,7 +328,7 @@ hooks/
|
|
|
258
328
|
|
|
259
329
|
---
|
|
260
330
|
|
|
261
|
-
**Version:**
|
|
262
|
-
**Ultima actualizacion:** 2025-12-
|
|
263
|
-
**Total de hooks:**
|
|
331
|
+
**Version:** 3.3.2
|
|
332
|
+
**Ultima actualizacion:** 2025-12-11
|
|
333
|
+
**Total de hooks:** 7 hooks (5 pre, 1 post, 1 metrics)
|
|
264
334
|
**Mantenido por:** Gaia (meta-agent)
|