feat: add one-click feature handoff flow
This commit is contained in:
@@ -33,6 +33,7 @@ BuildPulse v0.1 includes:
|
||||
- Pulse Log screen
|
||||
- Export screen
|
||||
- AI session prompt export for coding-agent handoff
|
||||
- One-click handoff prep from a selected feature
|
||||
- Appwrite-backed persistence on the Unraid server
|
||||
- Local cache fallback for resilience during backend hiccups
|
||||
- Pulse-shaped event records
|
||||
|
||||
@@ -192,6 +192,19 @@ Expected:
|
||||
- Contains recent pulses.
|
||||
- Is useful as an AI coder handoff.
|
||||
|
||||
### Test 5.5: Prepare AI handoff from selected feature
|
||||
|
||||
Steps:
|
||||
1. Open Feature Plan.
|
||||
2. Select a feature.
|
||||
3. Click `Prepare AI Handoff`.
|
||||
4. Confirm Export view opens with the selected feature loaded into `AI_SESSION_PROMPT.md`.
|
||||
|
||||
Expected:
|
||||
- Export view opens immediately.
|
||||
- Prompt focus feature matches the selected feature.
|
||||
- Prompt includes current goal, acceptance criteria, parking-lot guardrails, and recent relevant pulses.
|
||||
|
||||
## Manual Test Group 6 — Mobile Usability
|
||||
|
||||
### Test 6.1: Phone layout
|
||||
|
||||
+28
@@ -279,6 +279,15 @@ function App() {
|
||||
}))
|
||||
}
|
||||
|
||||
const openFeatureHandoff = (featureId: string) => {
|
||||
setPromptFeatureId(featureId)
|
||||
setPromptTarget('OpenClaw')
|
||||
setActiveTab('export')
|
||||
|
||||
const feature = appState.features.find((entry) => entry.id === featureId)
|
||||
setStatusMessage(feature ? `Prepared AI handoff for “${feature.title}”.` : 'Prepared AI handoff prompt.')
|
||||
}
|
||||
|
||||
const beginParkingEdit = (item: ParkingLotItem) => {
|
||||
setSelectedParkingId(item.id)
|
||||
setParkingDraft({
|
||||
@@ -601,6 +610,20 @@ function App() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{selectedFeature && (
|
||||
<section className="card quick-actions">
|
||||
<div>
|
||||
<strong>{selectedFeature.title}</strong>
|
||||
<p>Selected and ready. Shape it here, then kick a clean brief to your agent.</p>
|
||||
</div>
|
||||
<div className="button-inline-row">
|
||||
<button type="button" onClick={() => openFeatureHandoff(selectedFeature.id)}>
|
||||
Prepare AI Handoff
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
<div className="board-grid">
|
||||
{FEATURE_COLUMNS.map((column) => (
|
||||
<article key={column} className="column card">
|
||||
@@ -708,9 +731,14 @@ function App() {
|
||||
<button type="button" onClick={saveFeature}>{selectedFeature ? 'Save Changes' : 'Add Feature'}</button>
|
||||
<button type="button" className="ghost" onClick={resetFeatureDraft}>Clear</button>
|
||||
{selectedFeature && (
|
||||
<>
|
||||
<button type="button" className="ghost" onClick={() => openFeatureHandoff(selectedFeature.id)}>
|
||||
Prepare AI Handoff
|
||||
</button>
|
||||
<button type="button" className="danger" onClick={() => deleteFeature(selectedFeature.id)}>
|
||||
Delete Feature
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user