feat: flexible intake — deferred variables + prepared sessions (#103)

* feat: flexible intake — deferred variables + prepared sessions

Remove blocking intake form modal. Variables are now filled inline during
flow execution or pre-filled via prepared sessions. Adds PATCH /sessions/{id}/variables
endpoint, POST /sessions/prepare for session pre-staging, inline variable prompts
in StepDetail, editable Session Variables panel, and "Prepared for You" dashboard section.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: pass treeData directly to startSession to avoid stale state

setTree(treeData) hasn't committed when startSession runs immediately
after, so tree is still null and getStepsFromTree returns []. This
caused the step detail area to render empty on new session start.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: wire PrepareSessionModal entry point in Flow Library

Add "Prepare session" button (clipboard icon) to grid, list, and table
views for procedural/maintenance flows. Clicking fetches tree intake
fields and account members, then opens PrepareSessionModal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit was merged in pull request #103.
This commit is contained in:
chihlasm
2026-03-10 09:49:51 -04:00
committed by GitHub
parent 4727106141
commit ccd06c9ed4
25 changed files with 1214 additions and 102 deletions

View File

@@ -26,6 +26,7 @@ import { WeeklyCalendar } from '@/components/dashboard/WeeklyCalendar'
import { QuickActions } from '@/components/dashboard/QuickActions'
import { OpenSessions } from '@/components/dashboard/OpenSessions'
import { RecentActivity } from '@/components/dashboard/RecentActivity'
import { PreparedSessions } from '@/components/dashboard/PreparedSessions'
function timeAgo(dateStr: string): string {
const now = Date.now()
@@ -218,6 +219,7 @@ export function QuickStartPage() {
// Stats
const openSessions = activeSessions.length
const todaySessions = allSessions.filter(s => {
if (!s.started_at) return false
const d = new Date(s.started_at)
const now = new Date()
return d.toDateString() === now.toDateString()
@@ -226,14 +228,15 @@ export function QuickStartPage() {
// Open sessions for the new panel (3 oldest)
const openSessionItems = activeSessions
.sort((a, b) => new Date(a.started_at).getTime() - new Date(b.started_at).getTime())
.filter(s => s.started_at) // Exclude prepared sessions (started_at is null)
.sort((a, b) => new Date(a.started_at!).getTime() - new Date(b.started_at!).getTime())
.slice(0, 3)
.map(s => ({
id: s.id,
treeName: s.tree_snapshot?.name || 'Unknown',
treeId: s.tree_id,
treeType: (s.tree_snapshot as unknown as Record<string, unknown>)?.tree_type as string | undefined,
timeAgo: timeAgo(s.started_at),
timeAgo: timeAgo(s.started_at!),
}))
// recentSessionItems removed — replaced by RecentActivity component
@@ -335,7 +338,10 @@ export function QuickStartPage() {
</div>
</div>
{/* Row 3: Recent Activity */}
{/* Row 3: Prepared Sessions (only visible when sessions exist) */}
<PreparedSessions />
{/* Row 4: Recent Activity */}
<RecentActivity />
{/* ── Existing content below ── */}