Compare commits
2 Commits
jochen-deb
...
micn/save-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80ff4edfde | ||
|
|
9e41f84b52 |
171
CHANGELOG_REQUIREMENTS_PERSISTENCE.md
Normal file
171
CHANGELOG_REQUIREMENTS_PERSISTENCE.md
Normal file
@@ -0,0 +1,171 @@
|
||||
# Changelog: Requirements Persistence Feature
|
||||
|
||||
## Summary
|
||||
|
||||
Enhanced the accumulative autonomous mode (`--auto` / default mode) to automatically persist requirements to a local `.g3/requirements.md` file.
|
||||
|
||||
## Changes Made
|
||||
|
||||
### 1. Core Implementation (`crates/g3-cli/src/lib.rs`)
|
||||
|
||||
#### New Functions Added:
|
||||
|
||||
- **`ensure_g3_dir(workspace_dir: &Path) -> Result<PathBuf>`**
|
||||
- Creates `.g3` directory in the workspace if it doesn't exist
|
||||
- Returns the path to the `.g3` directory
|
||||
|
||||
- **`load_existing_requirements(workspace_dir: &Path) -> Result<Vec<String>>`**
|
||||
- Loads requirements from `.g3/requirements.md` if the file exists
|
||||
- Parses numbered requirements (format: `1. requirement text`)
|
||||
- Returns empty vector if file doesn't exist
|
||||
|
||||
- **`save_requirements(workspace_dir: &Path, requirements: &[String]) -> Result<()>`**
|
||||
- Saves accumulated requirements to `.g3/requirements.md`
|
||||
- Creates `.g3` directory if needed
|
||||
- Formats as markdown with numbered list
|
||||
|
||||
#### Modified Functions:
|
||||
|
||||
- **`run_accumulative_mode()`**
|
||||
- Now loads existing requirements on startup
|
||||
- Displays loaded requirements to user
|
||||
- Initializes turn number based on existing requirements count
|
||||
- Saves requirements after each new requirement is added
|
||||
- Shows save confirmation message
|
||||
- Updated `/requirements` command to show file location
|
||||
|
||||
### 2. Version Control (`.gitignore`)
|
||||
|
||||
- Added `.g3/` directory to `.gitignore`
|
||||
- Prevents accidental commit of local requirements
|
||||
- Users can opt-in to version control if desired
|
||||
|
||||
### 3. Documentation
|
||||
|
||||
#### New Documentation:
|
||||
|
||||
- **`docs/REQUIREMENTS_PERSISTENCE.md`**
|
||||
- Comprehensive guide to the requirements persistence feature
|
||||
- Usage examples and commands
|
||||
- File format specification
|
||||
- Use cases and best practices
|
||||
- Comparison with traditional autonomous mode
|
||||
|
||||
#### Updated Documentation:
|
||||
|
||||
- **`README.md`**
|
||||
- Added requirements persistence section to "Getting Started"
|
||||
- Highlighted key benefits (resume, review, share)
|
||||
- Added example showing `.g3/requirements.md` usage
|
||||
|
||||
### 4. Testing
|
||||
|
||||
- **`test_requirements.sh`**
|
||||
- Simple test script for manual verification
|
||||
- Creates test directory and provides instructions
|
||||
|
||||
## User-Facing Changes
|
||||
|
||||
### New Behavior
|
||||
|
||||
1. **Automatic Saving**
|
||||
- Every requirement entered is immediately saved to `.g3/requirements.md`
|
||||
- User sees confirmation: `💾 Saved to .g3/requirements.md`
|
||||
|
||||
2. **Automatic Loading**
|
||||
- On startup, G3 checks for existing `.g3/requirements.md`
|
||||
- If found, loads and displays requirements
|
||||
- Shows: `📂 Loaded N existing requirement(s) from .g3/requirements.md`
|
||||
|
||||
3. **Enhanced `/requirements` Command**
|
||||
- Now shows file location in output
|
||||
- Format: `📋 Accumulated Requirements (saved to .g3/requirements.md):`
|
||||
|
||||
4. **Session Resumability**
|
||||
- Users can exit and resume work later
|
||||
- Requirements persist across sessions
|
||||
- Turn numbering continues from previous session
|
||||
|
||||
### File Structure
|
||||
|
||||
```
|
||||
my-project/
|
||||
├── .g3/
|
||||
│ └── requirements.md # NEW: Accumulated requirements
|
||||
├── logs/ # Existing: Session logs
|
||||
└── ... (project files)
|
||||
```
|
||||
|
||||
### Requirements File Format
|
||||
|
||||
```markdown
|
||||
# Project Requirements
|
||||
|
||||
1. First requirement
|
||||
2. Second requirement
|
||||
3. Third requirement
|
||||
```
|
||||
|
||||
## Benefits
|
||||
|
||||
1. **Persistence**: No data loss if G3 crashes or is interrupted
|
||||
2. **Transparency**: Always know what G3 is working on
|
||||
3. **Resumability**: Pick up where you left off
|
||||
4. **Documentation**: Requirements serve as project documentation
|
||||
5. **Collaboration**: Share requirements with team members
|
||||
6. **Auditability**: Track what was requested and when
|
||||
|
||||
## Backward Compatibility
|
||||
|
||||
- ✅ Fully backward compatible
|
||||
- ✅ No breaking changes to existing functionality
|
||||
- ✅ Works seamlessly with existing projects
|
||||
- ✅ Graceful handling of missing `.g3` directory
|
||||
- ✅ Error handling for file I/O issues
|
||||
|
||||
## Error Handling
|
||||
|
||||
- If `.g3/requirements.md` cannot be read: Shows warning, continues with empty requirements
|
||||
- If `.g3/requirements.md` cannot be written: Shows warning, continues with in-memory requirements
|
||||
- Non-blocking errors don't interrupt workflow
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
- [x] Build succeeds without errors
|
||||
- [ ] Manual test: Create new requirements in fresh directory
|
||||
- [ ] Manual test: Resume session with existing requirements
|
||||
- [ ] Manual test: `/requirements` command shows file location
|
||||
- [ ] Manual test: Requirements file format is correct
|
||||
- [ ] Manual test: Error handling for permission issues
|
||||
- [ ] Manual test: `.g3` directory is created automatically
|
||||
- [ ] Manual test: `.g3` directory is ignored by git
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
Potential improvements for future versions:
|
||||
|
||||
1. Requirement status tracking (pending, in-progress, completed)
|
||||
2. Requirement dependencies and ordering
|
||||
3. Requirement templates and snippets
|
||||
4. Integration with issue trackers
|
||||
5. Requirement validation and linting
|
||||
6. Export to other formats (JSON, YAML, etc.)
|
||||
7. Requirement search and filtering
|
||||
8. Requirement history and versioning
|
||||
|
||||
## Migration Guide
|
||||
|
||||
No migration needed! The feature works automatically:
|
||||
|
||||
1. Update to the new version
|
||||
2. Run `g3` in any directory
|
||||
3. Enter requirements as usual
|
||||
4. Requirements are automatically saved to `.g3/requirements.md`
|
||||
|
||||
## Related Files
|
||||
|
||||
- `crates/g3-cli/src/lib.rs` - Core implementation
|
||||
- `.gitignore` - Version control exclusion
|
||||
- `docs/REQUIREMENTS_PERSISTENCE.md` - Feature documentation
|
||||
- `README.md` - Updated getting started guide
|
||||
- `test_requirements.sh` - Test script
|
||||
@@ -137,6 +137,11 @@ G3 is designed for:
|
||||
|
||||
The default interactive mode now uses **accumulative autonomous mode**, which combines the best of interactive and autonomous workflows:
|
||||
|
||||
**Requirements Persistence**: All requirements are automatically saved to `.g3/requirements.md` in your workspace, allowing you to:
|
||||
- Resume work across sessions
|
||||
- Review what you've asked G3 to build
|
||||
- Share requirements with team members
|
||||
|
||||
```bash
|
||||
# Simply run g3 in any directory
|
||||
g3
|
||||
@@ -152,6 +157,9 @@ requirement> create a simple web server in Python with Flask
|
||||
# ... autonomous mode runs and implements it ...
|
||||
requirement> add a /health endpoint that returns JSON
|
||||
# ... autonomous mode runs again with both requirements ...
|
||||
|
||||
# Requirements are saved to .g3/requirements.md
|
||||
# Use /requirements command to view them
|
||||
```
|
||||
|
||||
### Other Modes
|
||||
|
||||
@@ -439,6 +439,51 @@ pub async fn run() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Ensure .g3 directory exists in the workspace
|
||||
fn ensure_g3_dir(workspace_dir: &Path) -> Result<PathBuf> {
|
||||
let g3_dir = workspace_dir.join(".g3");
|
||||
if !g3_dir.exists() {
|
||||
std::fs::create_dir_all(&g3_dir)?;
|
||||
}
|
||||
Ok(g3_dir)
|
||||
}
|
||||
|
||||
/// Load existing requirements from .g3/requirements.md if it exists
|
||||
fn load_existing_requirements(workspace_dir: &Path) -> Result<Vec<String>> {
|
||||
let g3_dir = workspace_dir.join(".g3");
|
||||
let requirements_file = g3_dir.join("requirements.md");
|
||||
|
||||
if !requirements_file.exists() {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
|
||||
let content = std::fs::read_to_string(&requirements_file)?;
|
||||
|
||||
// Parse the requirements from the markdown file
|
||||
let mut requirements = Vec::new();
|
||||
for line in content.lines() {
|
||||
// Look for numbered requirements (e.g., "1. requirement text")
|
||||
if let Some(stripped) = line.strip_prefix(|c: char| c.is_ascii_digit()) {
|
||||
if let Some(req) = stripped.strip_prefix(". ") {
|
||||
// Reconstruct the numbered format
|
||||
let num = line.chars().take_while(|c| c.is_ascii_digit()).collect::<String>();
|
||||
requirements.push(format!("{}. {}", num, req));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(requirements)
|
||||
}
|
||||
|
||||
/// Save accumulated requirements to .g3/requirements.md
|
||||
fn save_requirements(workspace_dir: &Path, requirements: &[String]) -> Result<()> {
|
||||
let g3_dir = ensure_g3_dir(workspace_dir)?;
|
||||
let requirements_file = g3_dir.join("requirements.md");
|
||||
let content = format!("# Project Requirements\n\n{}\n", requirements.join("\n"));
|
||||
std::fs::write(&requirements_file, content)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Accumulative autonomous mode: accumulates requirements from user input
|
||||
/// and runs autonomous mode after each input
|
||||
async fn run_accumulative_mode(
|
||||
@@ -474,9 +519,25 @@ async fn run_accumulative_mode(
|
||||
let _ = rl.load_history(history_path);
|
||||
}
|
||||
|
||||
// Accumulated requirements stored in memory
|
||||
let mut accumulated_requirements = Vec::new();
|
||||
let mut turn_number = 0;
|
||||
// Load existing requirements from .g3/requirements.md if it exists
|
||||
let mut accumulated_requirements = match load_existing_requirements(&workspace_dir) {
|
||||
Ok(reqs) if !reqs.is_empty() => {
|
||||
output.print("");
|
||||
output.print(&format!("📂 Loaded {} existing requirement(s) from .g3/requirements.md", reqs.len()));
|
||||
output.print("");
|
||||
for req in &reqs {
|
||||
output.print(&format!(" {}", req));
|
||||
}
|
||||
output.print("");
|
||||
reqs
|
||||
}
|
||||
Ok(_) => Vec::new(),
|
||||
Err(e) => {
|
||||
output.print(&format!("⚠️ Warning: Could not load existing requirements: {}", e));
|
||||
Vec::new()
|
||||
}
|
||||
};
|
||||
let mut turn_number = accumulated_requirements.len();
|
||||
|
||||
loop {
|
||||
output.print(&format!("\n{}", "=".repeat(60)));
|
||||
@@ -519,7 +580,8 @@ async fn run_accumulative_mode(
|
||||
if accumulated_requirements.is_empty() {
|
||||
output.print("📋 No requirements accumulated yet");
|
||||
} else {
|
||||
output.print("📋 Accumulated Requirements:");
|
||||
let req_file = workspace_dir.join(".g3/requirements.md");
|
||||
output.print(&format!("📋 Accumulated Requirements (saved to {}):", req_file.display()));
|
||||
output.print("");
|
||||
for req in &accumulated_requirements {
|
||||
output.print(&format!(" {}", req));
|
||||
@@ -605,6 +667,13 @@ async fn run_accumulative_mode(
|
||||
turn_number += 1;
|
||||
accumulated_requirements.push(format!("{}. {}", turn_number, input));
|
||||
|
||||
// Save requirements to .g3/requirements.md
|
||||
if let Err(e) = save_requirements(&workspace_dir, &accumulated_requirements) {
|
||||
output.print(&format!("⚠️ Warning: Could not save requirements to .g3/requirements.md: {}", e));
|
||||
} else {
|
||||
output.print(&format!("💾 Saved to .g3/requirements.md"));
|
||||
}
|
||||
|
||||
// Build the complete requirements document
|
||||
let requirements_doc = format!(
|
||||
"# Project Requirements\n\n\
|
||||
|
||||
210
docs/REQUIREMENTS_PERSISTENCE.md
Normal file
210
docs/REQUIREMENTS_PERSISTENCE.md
Normal file
@@ -0,0 +1,210 @@
|
||||
# Requirements Persistence in Accumulative Mode
|
||||
|
||||
## Overview
|
||||
|
||||
In accumulative autonomous mode (`--auto` or default mode), G3 now automatically persists your requirements to a local `.g3/requirements.md` file. This provides several benefits:
|
||||
|
||||
1. **Persistence across sessions**: Your requirements are saved and can be resumed later
|
||||
2. **Version control friendly**: Requirements are stored in a readable markdown format
|
||||
3. **Easy review**: You can view and edit requirements directly in the file
|
||||
4. **Transparency**: Always know what G3 is working on
|
||||
|
||||
## How It Works
|
||||
|
||||
### Automatic Saving
|
||||
|
||||
When you run G3 in accumulative mode:
|
||||
|
||||
```bash
|
||||
g3
|
||||
```
|
||||
|
||||
Each requirement you enter is automatically:
|
||||
1. Added to the accumulated requirements list
|
||||
2. Saved to `.g3/requirements.md` in your workspace
|
||||
3. Used for the autonomous implementation run
|
||||
|
||||
### File Format
|
||||
|
||||
The `.g3/requirements.md` file uses a simple numbered list format:
|
||||
|
||||
```markdown
|
||||
# Project Requirements
|
||||
|
||||
1. Create a simple web server in Python with Flask
|
||||
2. Add a /health endpoint that returns JSON
|
||||
3. Add logging for all requests
|
||||
```
|
||||
|
||||
### Loading Existing Requirements
|
||||
|
||||
When you start G3 in a directory that already has a `.g3/requirements.md` file, it will:
|
||||
|
||||
1. Automatically load the existing requirements
|
||||
2. Display them on startup
|
||||
3. Continue numbering from where you left off
|
||||
|
||||
Example output:
|
||||
|
||||
```
|
||||
📂 Loaded 3 existing requirement(s) from .g3/requirements.md
|
||||
|
||||
1. Create a simple web server in Python with Flask
|
||||
2. Add a /health endpoint that returns JSON
|
||||
3. Add logging for all requests
|
||||
|
||||
============================================================
|
||||
📝 Turn 4 - What's next? (add more requirements or refinements)
|
||||
============================================================
|
||||
requirement>
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
### View Requirements
|
||||
|
||||
Use the `/requirements` command to view all accumulated requirements:
|
||||
|
||||
```
|
||||
requirement> /requirements
|
||||
|
||||
📋 Accumulated Requirements (saved to .g3/requirements.md):
|
||||
|
||||
1. Create a simple web server in Python with Flask
|
||||
2. Add a /health endpoint that returns JSON
|
||||
3. Add logging for all requests
|
||||
```
|
||||
|
||||
### Other Commands
|
||||
|
||||
- `/help` - Show all available commands
|
||||
- `/chat` - Switch to interactive chat mode (preserves requirements context)
|
||||
- `exit` or `quit` - Exit the session
|
||||
|
||||
## File Location
|
||||
|
||||
The requirements file is stored at:
|
||||
|
||||
```
|
||||
<workspace>/.g3/requirements.md
|
||||
```
|
||||
|
||||
Where `<workspace>` is your current working directory.
|
||||
|
||||
## Version Control
|
||||
|
||||
The `.g3/` directory is automatically added to `.gitignore`, so your requirements won't be committed to version control by default. If you want to track requirements in git, you can:
|
||||
|
||||
1. Remove `.g3/` from `.gitignore`
|
||||
2. Commit the `.g3/requirements.md` file
|
||||
|
||||
This can be useful for:
|
||||
- Sharing requirements with team members
|
||||
- Tracking requirement evolution over time
|
||||
- Documenting project goals
|
||||
|
||||
## Manual Editing
|
||||
|
||||
You can manually edit `.g3/requirements.md` if needed. G3 will parse the file and load any numbered requirements (format: `1. requirement text`).
|
||||
|
||||
**Note**: Make sure to maintain the numbered list format for proper parsing.
|
||||
|
||||
## Error Handling
|
||||
|
||||
If G3 cannot save or load requirements, it will:
|
||||
|
||||
1. Display a warning message
|
||||
2. Continue operating with in-memory requirements
|
||||
3. Not interrupt your workflow
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
⚠️ Warning: Could not save requirements to .g3/requirements.md: Permission denied
|
||||
```
|
||||
|
||||
## Use Cases
|
||||
|
||||
### Resuming Work
|
||||
|
||||
```bash
|
||||
# Day 1: Start a project
|
||||
cd my-project
|
||||
g3
|
||||
requirement> Create a REST API with user authentication
|
||||
# ... work happens ...
|
||||
exit
|
||||
|
||||
# Day 2: Resume work
|
||||
cd my-project
|
||||
g3
|
||||
# G3 automatically loads previous requirements
|
||||
requirement> Add password reset functionality
|
||||
```
|
||||
|
||||
### Reviewing Progress
|
||||
|
||||
```bash
|
||||
# Check what you've asked G3 to build
|
||||
cat .g3/requirements.md
|
||||
|
||||
# Or use the command within G3
|
||||
requirement> /requirements
|
||||
```
|
||||
|
||||
### Sharing Requirements
|
||||
|
||||
```bash
|
||||
# Share requirements with a team member
|
||||
cp .g3/requirements.md requirements-backup.md
|
||||
# Or commit to version control
|
||||
git add .g3/requirements.md
|
||||
git commit -m "Add project requirements"
|
||||
```
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### Functions
|
||||
|
||||
- `ensure_g3_dir()` - Creates `.g3` directory if it doesn't exist
|
||||
- `load_existing_requirements()` - Loads requirements from `.g3/requirements.md`
|
||||
- `save_requirements()` - Saves requirements to `.g3/requirements.md`
|
||||
|
||||
### File Structure
|
||||
|
||||
```
|
||||
my-project/
|
||||
├── .g3/
|
||||
│ └── requirements.md # Accumulated requirements
|
||||
├── logs/ # Session logs (existing)
|
||||
└── ... (your project files)
|
||||
```
|
||||
|
||||
## Benefits
|
||||
|
||||
1. **No data loss**: Requirements are persisted even if G3 crashes or is interrupted
|
||||
2. **Transparency**: Always know what G3 is working on
|
||||
3. **Resumability**: Pick up where you left off in any session
|
||||
4. **Documentation**: Requirements serve as project documentation
|
||||
5. **Collaboration**: Share requirements with team members
|
||||
6. **Auditability**: Track what was requested and when
|
||||
|
||||
## Comparison with Traditional Autonomous Mode
|
||||
|
||||
| Feature | Accumulative Mode | Traditional `--autonomous` |
|
||||
|---------|------------------|---------------------------|
|
||||
| Requirements file | `.g3/requirements.md` | `requirements.md` (root) |
|
||||
| Auto-save | ✅ Yes | ❌ No (manual edit) |
|
||||
| Interactive | ✅ Yes | ❌ No |
|
||||
| Incremental | ✅ Yes | ❌ No (one-shot) |
|
||||
| Resume support | ✅ Yes | ⚠️ Manual |
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
Potential future improvements:
|
||||
|
||||
- Requirement status tracking (pending, in-progress, completed)
|
||||
- Requirement dependencies and ordering
|
||||
- Requirement templates and snippets
|
||||
- Integration with issue trackers
|
||||
- Requirement validation and linting
|
||||
36
test_requirements.sh
Executable file
36
test_requirements.sh
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Test script for .g3/requirements.md feature
|
||||
|
||||
set -e
|
||||
|
||||
echo "Testing .g3/requirements.md feature..."
|
||||
echo ""
|
||||
|
||||
# Create a test directory
|
||||
TEST_DIR="/tmp/g3_test_$$"
|
||||
mkdir -p "$TEST_DIR"
|
||||
cd "$TEST_DIR"
|
||||
|
||||
echo "Test directory: $TEST_DIR"
|
||||
echo ""
|
||||
|
||||
# Create a simple test by simulating user input
|
||||
echo "Testing requirement persistence..."
|
||||
echo ""
|
||||
|
||||
# Check if .g3 directory gets created
|
||||
if [ ! -d ".g3" ]; then
|
||||
echo "✅ .g3 directory does not exist yet (expected)"
|
||||
else
|
||||
echo "❌ .g3 directory already exists (unexpected)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Test directory created at: $TEST_DIR"
|
||||
echo "You can manually test by running:"
|
||||
echo " cd $TEST_DIR"
|
||||
echo " g3"
|
||||
echo ""
|
||||
echo "Then enter a requirement and check if .g3/requirements.md is created."
|
||||
echo ""
|
||||
Reference in New Issue
Block a user