Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions apps/backend/core/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import os
import threading
import time
from collections.abc import Callable
from pathlib import Path
from typing import Any

Expand Down Expand Up @@ -536,6 +537,7 @@ def create_client(
betas: list[str] | None = None,
effort_level: str | None = None,
fast_mode: bool = False,
stderr_callback: Callable[[str], None] | None = None,
) -> ClaudeSDKClient:
"""
Create a Claude Agent SDK client with multi-layered security.
Expand Down Expand Up @@ -571,6 +573,8 @@ def create_client(
the "user" setting source so the CLI reads fastMode from
~/.claude/settings.json. Requires extra usage enabled on Claude
subscription; falls back to standard speed automatically.
stderr_callback: Optional callback invoked with each stderr line emitted
by the Claude CLI process.

Returns:
Configured ClaudeSDKClient
Expand Down Expand Up @@ -959,6 +963,9 @@ def create_client(
"enable_file_checkpointing": True,
}

if stderr_callback:
options_kwargs["stderr"] = stderr_callback

# Fast mode: enable user setting source so CLI reads fastMode from
# ~/.claude/settings.json. Without this, the SDK's default --setting-sources ""
# blocks all filesystem settings and the CLI never sees fastMode: true.
Expand Down
72 changes: 41 additions & 31 deletions apps/backend/prompts/spec_quick.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,46 +31,46 @@ That's it. No deep analysis needed.

## PHASE 2: CREATE MINIMAL SPEC

Create a concise `spec.md`:
Create a concise `spec.md` that includes the required validator sections:

```bash
cat > spec.md << 'EOF'
# Quick Spec: [Task Name]
# Specification: [Task Name]

## Task
[One sentence description]
## Overview
[One paragraph describing what is being changed and why]

## Files to Modify
## Workflow Type
**Type**: simple

## Task Scope
### Files to Modify
- `[path/to/file]` - [what to change]

## Change Details
### Change Details
[Brief description of the change - a few sentences max]

## Verification
## Success Criteria
- [ ] [How to verify the change works]

## Notes
[Any gotchas or considerations - optional]
EOF
```

**Keep it short!** A simple spec should be 20-50 lines, not 200+.
**Keep it short!** A simple spec should be concise and focused.

---

## PHASE 3: CREATE SIMPLE PLAN

Create `implementation_plan.json`:
Create `implementation_plan.json` with current schema fields:

```bash
cat > implementation_plan.json << 'EOF'
{
"spec_name": "[spec-name]",
"feature": "[task description]",
"workflow_type": "simple",
"total_phases": 1,
"recommended_workers": 1,
"phases": [
{
"id": "phase-1",
"phase": 1,
"name": "Implementation",
"description": "[task description]",
Expand All @@ -86,17 +86,19 @@ cat > implementation_plan.json << 'EOF'
"patterns_from": [],
"verification": {
"type": "manual",
"run": "[verification step]"
"instructions": "[verification step]"
}
}
]
}
],
"metadata": {
"created_at": "[timestamp]",
"complexity": "simple",
"estimated_sessions": 1
}
"summary": {
"total_phases": 1,
"total_subtasks": 1,
"recommended_workers": 1
},
"created_at": "[timestamp]",
"updated_at": "[timestamp]"
}
EOF
```
Expand Down Expand Up @@ -146,18 +148,22 @@ Ready for implementation.

**spec.md**:
```markdown
# Quick Spec: Button Color Change
# Specification: Button Color Change

## Task
## Overview
Update primary button color from blue (#3B82F6) to green (#22C55E).

## Files to Modify
## Workflow Type
**Type**: simple

## Task Scope
### Files to Modify
- `src/components/Button.tsx` - Update color constant

## Change Details
### Change Details
Change the `primaryColor` variable from `#3B82F6` to `#22C55E`.

## Verification
## Success Criteria
- [ ] Buttons appear green in the UI
- [ ] No console errors
```
Expand All @@ -168,18 +174,22 @@ Change the `primaryColor` variable from `#3B82F6` to `#22C55E`.

**spec.md**:
```markdown
# Quick Spec: Fix Welcome Typo
# Specification: Fix Welcome Typo

## Task
## Overview
Correct spelling of "recieve" to "receive" in welcome message.

## Files to Modify
## Workflow Type
**Type**: simple

## Task Scope
### Files to Modify
- `src/pages/Home.tsx` - Fix typo on line 42

## Change Details
### Change Details
Find "You will recieve" and change to "You will receive".

## Verification
## Success Criteria
- [ ] Welcome message displays correctly
```

Expand Down
52 changes: 45 additions & 7 deletions apps/backend/spec/phases/spec_phases.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,16 @@ async def phase_quick_spec(self) -> PhaseResult:
plan_file = self.spec_dir / "implementation_plan.json"

if spec_file.exists() and plan_file.exists():
self.ui.print_status("Quick spec already exists", "success")
return PhaseResult(
"quick_spec", True, [str(spec_file), str(plan_file)], [], 0
spec_valid = self.spec_validator.validate_spec_document().valid
plan_valid = self.spec_validator.validate_implementation_plan().valid
if spec_valid and plan_valid:
self.ui.print_status("Quick spec already exists", "success")
return PhaseResult(
"quick_spec", True, [str(spec_file), str(plan_file)], [], 0
)

self.ui.print_status(
"Quick spec files exist but are invalid, regenerating...", "warning"
)

is_greenfield = self._check_and_log_greenfield()
Expand Down Expand Up @@ -91,15 +98,46 @@ async def phase_quick_spec(self) -> PhaseResult:
phase_name="quick_spec",
)

if success and spec_file.exists():
if success:
# Create minimal plan if agent didn't
if not plan_file.exists():
writer.create_minimal_plan(self.spec_dir, self.task_description)

self.ui.print_status("Quick spec created", "success")
return PhaseResult(
"quick_spec", True, [str(spec_file), str(plan_file)], [], attempt
spec_valid = (
spec_file.exists()
and self.spec_validator.validate_spec_document().valid
)
plan_valid = (
plan_file.exists()
and self.spec_validator.validate_implementation_plan().valid
)

if not plan_valid and plan_file.exists():
from ..validate_pkg.auto_fix import auto_fix_plan

if auto_fix_plan(self.spec_dir):
plan_valid = (
self.spec_validator.validate_implementation_plan().valid
)

if spec_valid and plan_valid:
self.ui.print_status("Quick spec created", "success")
return PhaseResult(
"quick_spec",
True,
[str(spec_file), str(plan_file)],
[],
attempt,
)

errors.append(
f"Attempt {attempt + 1}: Quick spec output invalid "
f"(spec_valid={spec_valid}, plan_valid={plan_valid})"
)
self.ui.print_status(
"Quick spec created files but validation failed", "error"
)
continue

errors.append(f"Attempt {attempt + 1}: Quick spec agent failed")

Expand Down
Loading
Loading