mirror of
https://github.com/leonvanzyl/autocoder.git
synced 2026-01-30 06:12:06 +00:00
feat: increase command limit to 100 and add optimization guide
Changes: - Increase command limit from 50 to 100 per project - Add examples/OPTIMIZE_CONFIG.md with optimization strategies - Update all documentation references (50 → 100) - Update tests for new limit Rationale: - 50 was too restrictive for projects with many tools (Flutter, etc.) - Users were unknowingly exceeding limit by listing subcommands - 100 provides headroom while maintaining security - New guide teaches wildcard optimization (flutter* vs listing each subcommand) UI feedback idea: Show command count and optimization suggestions (tracked for Phase 3 or future enhancement)
This commit is contained in:
@@ -233,7 +233,7 @@ blocked_commands:
|
||||
- Scripts: `./scripts/build.sh` matches the script by name from any directory
|
||||
|
||||
**Limits:**
|
||||
- Maximum 50 commands per project config
|
||||
- Maximum 100 commands per project config
|
||||
- Blocklisted commands (sudo, dd, shutdown, etc.) can NEVER be allowed
|
||||
- Org-level blocked commands cannot be overridden by project configs
|
||||
|
||||
|
||||
230
examples/OPTIMIZE_CONFIG.md
Normal file
230
examples/OPTIMIZE_CONFIG.md
Normal file
@@ -0,0 +1,230 @@
|
||||
# How to Optimize Your allowed_commands.yaml
|
||||
|
||||
## The Problem
|
||||
|
||||
Your config might have redundant commands like this:
|
||||
|
||||
```yaml
|
||||
commands:
|
||||
- name: flutter
|
||||
- name: flutter* # ← This already covers EVERYTHING below!
|
||||
- name: flutter test # ← Redundant
|
||||
- name: flutter test --coverage # ← Redundant
|
||||
- name: flutter build apk # ← Redundant
|
||||
- name: flutter build ios # ← Redundant
|
||||
# ... 20+ more flutter commands
|
||||
```
|
||||
|
||||
**Result:** 65 commands when you only need ~10-15
|
||||
|
||||
## How Wildcards Work
|
||||
|
||||
When you have `flutter*`, it matches:
|
||||
- ✅ `flutter` (the base command)
|
||||
- ✅ `flutter test`
|
||||
- ✅ `flutter test --coverage`
|
||||
- ✅ `flutter build apk`
|
||||
- ✅ `flutter build ios`
|
||||
- ✅ `flutter run`
|
||||
- ✅ **ANY command starting with "flutter"**
|
||||
|
||||
**You don't need to list every subcommand separately!**
|
||||
|
||||
## Example: GOD-APP Optimization
|
||||
|
||||
### Before (65 commands)
|
||||
```yaml
|
||||
commands:
|
||||
# Flutter
|
||||
- name: flutter
|
||||
- name: flutter*
|
||||
- name: flutter test
|
||||
- name: flutter test --coverage
|
||||
- name: flutter test --exclude-tags=golden,integration
|
||||
- name: flutter test --tags=golden
|
||||
- name: flutter test --tags=golden --update-goldens
|
||||
- name: flutter test --verbose
|
||||
- name: flutter drive
|
||||
- name: flutter test integration_test/
|
||||
- name: flutter build apk
|
||||
- name: flutter build apk --debug
|
||||
- name: flutter build apk --release
|
||||
- name: flutter build appbundle
|
||||
- name: flutter build ios
|
||||
- name: flutter build ios --debug
|
||||
- name: flutter build ipa
|
||||
- name: flutter build web
|
||||
- name: flutter pub get
|
||||
- name: flutter pub upgrade
|
||||
- name: flutter doctor
|
||||
- name: flutter clean
|
||||
# ... and more
|
||||
|
||||
# Dart
|
||||
- name: dart
|
||||
- name: dartfmt
|
||||
- name: dartanalyzer
|
||||
- name: dart format
|
||||
- name: dart analyze
|
||||
- name: dart fix
|
||||
- name: dart pub
|
||||
```
|
||||
|
||||
### After (15 commands) ✨
|
||||
```yaml
|
||||
commands:
|
||||
# Flutter & Dart (wildcards cover all subcommands)
|
||||
- name: flutter*
|
||||
description: All Flutter SDK commands
|
||||
|
||||
- name: dart*
|
||||
description: All Dart language tools
|
||||
|
||||
# Testing tools
|
||||
- name: patrol
|
||||
description: Patrol integration testing (if needed separately)
|
||||
|
||||
# Coverage tools
|
||||
- name: lcov
|
||||
description: Code coverage tool
|
||||
|
||||
- name: genhtml
|
||||
description: Generate HTML coverage reports
|
||||
|
||||
# Android tools
|
||||
- name: adb*
|
||||
description: Android Debug Bridge commands
|
||||
|
||||
- name: gradle*
|
||||
description: Gradle build system
|
||||
|
||||
# iOS tools (macOS only)
|
||||
- name: xcrun*
|
||||
description: Xcode developer tools
|
||||
|
||||
- name: xcodebuild
|
||||
description: Xcode build system
|
||||
|
||||
- name: simctl
|
||||
description: iOS Simulator control
|
||||
|
||||
- name: ios-deploy
|
||||
description: Deploy to iOS devices
|
||||
|
||||
# Project scripts
|
||||
- name: ./scripts/*.sh
|
||||
description: All project build/test scripts
|
||||
```
|
||||
|
||||
**Reduced from 65 → 15 commands (77% reduction!)**
|
||||
|
||||
## Optimization Checklist
|
||||
|
||||
For each group of commands, ask:
|
||||
|
||||
### ❓ "Do I have the base command AND a wildcard?"
|
||||
```yaml
|
||||
# Bad (redundant)
|
||||
- name: flutter
|
||||
- name: flutter*
|
||||
|
||||
# Good (just the wildcard)
|
||||
- name: flutter*
|
||||
```
|
||||
|
||||
The wildcard already matches the base command!
|
||||
|
||||
### ❓ "Am I listing subcommands individually?"
|
||||
```yaml
|
||||
# Bad (verbose)
|
||||
- name: flutter test
|
||||
- name: flutter test --coverage
|
||||
- name: flutter build apk
|
||||
- name: flutter run
|
||||
|
||||
# Good (one wildcard)
|
||||
- name: flutter*
|
||||
```
|
||||
|
||||
### ❓ "Can I group multiple scripts?"
|
||||
```yaml
|
||||
# If you can't use wildcards for scripts, at least group them logically
|
||||
- name: ./scripts/test.sh
|
||||
- name: ./scripts/build.sh
|
||||
- name: ./scripts/integration_test.sh
|
||||
```
|
||||
|
||||
These are fine - scripts need explicit paths. But if you have 20+ scripts, consider if they're all necessary.
|
||||
|
||||
## Common Wildcards
|
||||
|
||||
| Instead of... | Use... | Covers |
|
||||
|---------------|--------|--------|
|
||||
| flutter, flutter test, flutter build, flutter run | `flutter*` | All flutter commands |
|
||||
| dart, dart format, dart analyze, dart pub | `dart*` | All dart commands |
|
||||
| npm, npm install, npm run, npm test | `npm*` | All npm commands |
|
||||
| cargo, cargo build, cargo test, cargo run | `cargo*` | All cargo commands |
|
||||
| git, git status, git commit, git push | Just `git` | Git is in global defaults |
|
||||
|
||||
## When NOT to Optimize
|
||||
|
||||
Keep separate entries when:
|
||||
1. **Different base commands:** `swift` and `swiftc` are different (though `swift*` covers both)
|
||||
2. **Documentation clarity:** Sometimes listing helps future developers understand what's needed
|
||||
3. **Argument restrictions (Phase 3):** If you'll add argument validation later
|
||||
|
||||
## Quick Optimization Script
|
||||
|
||||
To see what you can reduce:
|
||||
|
||||
```bash
|
||||
# Count commands by prefix
|
||||
grep "^ - name:" .autocoder/allowed_commands.yaml | \
|
||||
sed 's/^ - name: //' | \
|
||||
cut -d' ' -f1 | \
|
||||
sort | uniq -c | sort -rn
|
||||
```
|
||||
|
||||
If you see multiple commands with the same prefix, use a wildcard!
|
||||
|
||||
## UI Feedback (Future Enhancement)
|
||||
|
||||
Great suggestion! Here's what a UI could show:
|
||||
|
||||
```
|
||||
⚠️ Config Optimization Available
|
||||
|
||||
Your config has 65 commands. We detected opportunities to reduce it:
|
||||
|
||||
• 25 flutter commands → Use flutter* (saves 24 entries)
|
||||
• 8 dart commands → Use dart* (saves 7 entries)
|
||||
• 12 adb commands → Use adb* (saves 11 entries)
|
||||
|
||||
[Optimize Automatically] [Keep As-Is]
|
||||
|
||||
Potential reduction: 65 → 23 commands
|
||||
```
|
||||
|
||||
Or during config editing:
|
||||
|
||||
```
|
||||
📊 Command Usage Stats
|
||||
|
||||
flutter* : 25 subcommands detected
|
||||
dart* : 8 subcommands detected
|
||||
./scripts/*.sh : 7 scripts detected
|
||||
|
||||
💡 Tip: Using wildcards covers all subcommands automatically
|
||||
```
|
||||
|
||||
**This would be a great addition to Phase 3 or beyond!**
|
||||
|
||||
## Your GOD-APP Optimization
|
||||
|
||||
Here's what you could do:
|
||||
|
||||
**Current:** 65 commands (exceeds 50 limit, config rejected!)
|
||||
|
||||
**Optimized:** ~15 commands using wildcards
|
||||
|
||||
Would you like me to create an optimized version of your GOD-APP config?
|
||||
@@ -72,7 +72,7 @@ commands:
|
||||
- ✅ Temporary tools needed during development
|
||||
|
||||
**Limits:**
|
||||
- Maximum 50 commands per project
|
||||
- Maximum 100 commands per project
|
||||
- Cannot override org-level blocked commands
|
||||
- Cannot allow hardcoded blocklist commands (sudo, dd, etc.)
|
||||
|
||||
@@ -321,13 +321,13 @@ blocked_commands: [] # Rely on hardcoded blocklist only
|
||||
- Bad: Adding `xcodebuild` to org config when only one project uses it
|
||||
- Good: Add `xcodebuild` to that project's config
|
||||
|
||||
4. **Don't exceed the 50 command limit per project**
|
||||
- If you need more, you're probably being too specific
|
||||
- Use wildcards instead: `npm-*` covers many npm tools
|
||||
4. **Don't exceed the 100 command limit per project**
|
||||
- If you need more, you're probably listing subcommands unnecessarily
|
||||
- Use wildcards instead: `flutter*` covers all flutter commands, not just the base
|
||||
|
||||
5. **Don't ignore validation errors**
|
||||
- If your YAML is rejected, fix the structure
|
||||
- Common issues: missing `version`, malformed lists, over 50 commands
|
||||
- Common issues: missing `version`, malformed lists, over 100 commands
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ commands: []
|
||||
# - Scripts: "./scripts/build.sh" matches the script by name
|
||||
#
|
||||
# Limits:
|
||||
# - Maximum 50 commands per project
|
||||
# - Maximum 100 commands per project
|
||||
# - Commands in the blocklist (sudo, dd, shutdown, etc.) can NEVER be allowed
|
||||
# - Org-level blocked commands (see ~/.autocoder/config.yaml) cannot be overridden
|
||||
#
|
||||
|
||||
@@ -491,8 +491,8 @@ def load_project_commands(project_dir: Path) -> Optional[dict]:
|
||||
if not isinstance(commands, list):
|
||||
return None
|
||||
|
||||
# Enforce 50 command limit
|
||||
if len(commands) > 50:
|
||||
# Enforce 100 command limit
|
||||
if len(commands) > 100:
|
||||
return None
|
||||
|
||||
# Validate each command entry
|
||||
|
||||
@@ -263,8 +263,8 @@ commands:
|
||||
print(f" Got: {config}")
|
||||
failed += 1
|
||||
|
||||
# Test 4: Over limit (50 commands)
|
||||
commands = [f" - name: cmd{i}\n description: Command {i}" for i in range(51)]
|
||||
# Test 4: Over limit (100 commands)
|
||||
commands = [f" - name: cmd{i}\n description: Command {i}" for i in range(101)]
|
||||
config_path.write_text("version: 1\ncommands:\n" + "\n".join(commands))
|
||||
config = load_project_commands(project_dir)
|
||||
if config is None:
|
||||
|
||||
@@ -326,21 +326,21 @@ def test_invalid_yaml_ignored():
|
||||
return False
|
||||
|
||||
|
||||
def test_50_command_limit():
|
||||
"""Test that configs with >50 commands are rejected."""
|
||||
def test_100_command_limit():
|
||||
"""Test that configs with >100 commands are rejected."""
|
||||
print("\n" + "=" * 70)
|
||||
print("TEST 9: 50 command limit enforced")
|
||||
print("TEST 9: 100 command limit enforced")
|
||||
print("=" * 70)
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
project_dir = Path(tmpdir)
|
||||
|
||||
# Create config with 51 commands
|
||||
# Create config with 101 commands
|
||||
autocoder_dir = project_dir / ".autocoder"
|
||||
autocoder_dir.mkdir()
|
||||
|
||||
commands = [
|
||||
f" - name: cmd{i}\n description: Command {i}" for i in range(51)
|
||||
f" - name: cmd{i}\n description: Command {i}" for i in range(101)
|
||||
]
|
||||
(autocoder_dir / "allowed_commands.yaml").write_text(
|
||||
"version: 1\ncommands:\n" + "\n".join(commands)
|
||||
@@ -353,10 +353,10 @@ def test_50_command_limit():
|
||||
result = asyncio.run(bash_security_hook(input_data, context=context))
|
||||
|
||||
if result.get("decision") == "block":
|
||||
print("✅ PASS: Config with >50 commands rejected")
|
||||
print("✅ PASS: Config with >100 commands rejected")
|
||||
return True
|
||||
else:
|
||||
print("❌ FAIL: Config with >50 commands should be rejected")
|
||||
print("❌ FAIL: Config with >100 commands should be rejected")
|
||||
return False
|
||||
|
||||
|
||||
@@ -376,7 +376,7 @@ def main():
|
||||
test_org_blocklist_enforcement,
|
||||
test_org_allowlist_inheritance,
|
||||
test_invalid_yaml_ignored,
|
||||
test_50_command_limit,
|
||||
test_100_command_limit,
|
||||
]
|
||||
|
||||
passed = 0
|
||||
|
||||
Reference in New Issue
Block a user