// Wrap-up ritual — fires when a burst finishes or a task is marked done. // Forces the user to organize "open loops" (random ideas, follow-ups, // new thoughts) into their proper homes BEFORE moving on. // // Routes per loop: // • Zip → Brain zips (kind=dump) // • Idea → Brain zips (kind=idea) // • →P → sub-task on a chosen priority // • Discard // // Plus a win to log + checkbox to mark the source task as done. function Wrap() { const { state, addLoop, routeLoop, setWrapWin, completeWrap, dismissWrap } = useStore(); const w = state.wrap; if (!w.active) return null; const [draft, setDraft] = React.useState(''); const [markDone, setMarkDone] = React.useState(true); const inputRef = React.useRef(null); React.useEffect(() => { // focus the loop input on open setTimeout(() => inputRef.current?.focus(), 250); }, []); const submitLoop = (e) => { e?.preventDefault(); if (!draft.trim()) return; addLoop(draft.trim()); setDraft(''); inputRef.current?.focus(); }; const stats = { total: w.loops.length, routed: w.loops.filter((l) => l.routed).length, pending: w.loops.filter((l) => !l.routed).length, }; const close = () => { completeWrap({ markTaskDone: markDone }); }; return (
{ if (e.target === e.currentTarget) dismissWrap(); }}>
Burst complete · close the loops

Nice. You worked on "{w.taskLabel}".

60 seconds to sort what came up, before you walk off.
{/* Task-done toggle, only if there's a task */} {w.taskId && ( )} {/* Loops capture */}
Open loops Random stuff that came up. Type, ↵, then route each one.
setDraft(e.target.value)} placeholder='e.g. "follow up with Anna about pricing", "read that Sequoia memo", "Tella has 4K export now?"' />
{w.loops.map((l) => ( !p.done)} onRoute={(dest) => routeLoop(l.id, dest)}/> ))} {w.loops.length === 0 && (
Nothing came up? Skip ahead.
)}
{/* Win to log */}
Win to log · optional Something to remember went well
setWrapWin(e.target.value)} placeholder='e.g. "traction slide finally clicks", "closed Liesel reference check"' />
{stats.routed}/{stats.total} loops sorted {stats.pending > 0 && ( · {stats.pending} still pending )} wrap streak {state.wrapStreak || 0}
); } function LoopRow({ loop, priorities, onRoute }) { const [menuOpen, setMenuOpen] = React.useState(false); const btnRef = React.useRef(null); if (loop.routed) { const lbl = loop.routed === 'zip' ? 'in zips' : loop.routed === 'idea' ? 'in ideas' : loop.routed === 'discard' ? 'discarded' : loop.routed.startsWith('priority:') ? `→ ${priorities.find((p) => p.id === loop.routed.slice(9))?.title?.slice(0, 28) || 'priority'}…` : loop.routed; return (
{loop.text} {lbl}
); } return (
{loop.text}
{menuOpen && (
setMenuOpen(false)}>
Add as sub-task to…
{priorities.map((p, i) => ( ))} {priorities.length === 0 && (
No active priorities
)}
)}
); } Object.assign(window, { Wrap });