@@ -19,11 +19,18 @@ import {
1919 type ObsidianConfig ,
2020 type BearConfig ,
2121} from "./integrations" ;
22+ import {
23+ generateSlug ,
24+ savePlan ,
25+ saveAnnotations ,
26+ saveFinalSnapshot ,
27+ } from "./storage" ;
2228
2329// Re-export utilities
2430export { isRemoteSession , getServerPort } from "./remote" ;
2531export { openBrowser } from "./browser" ;
2632export * from "./integrations" ;
33+ export * from "./storage" ;
2734
2835// --- Types ---
2936
@@ -46,7 +53,11 @@ export interface ServerResult {
4653 /** Whether running in remote mode */
4754 isRemote : boolean ;
4855 /** Wait for user decision (approve/deny) */
49- waitForDecision : ( ) => Promise < { approved : boolean ; feedback ?: string } > ;
56+ waitForDecision : ( ) => Promise < {
57+ approved : boolean ;
58+ feedback ?: string ;
59+ savedPath ?: string ;
60+ } > ;
5061 /** Stop the server */
5162 stop : ( ) => void ;
5263}
@@ -73,13 +84,23 @@ export async function startPlannotatorServer(
7384 const isRemote = isRemoteSession ( ) ;
7485 const configuredPort = getServerPort ( ) ;
7586
87+ // Generate slug and save plan immediately
88+ const slug = generateSlug ( plan ) ;
89+ const planPath = savePlan ( slug , plan ) ;
90+
7691 // Decision promise
77- let resolveDecision : ( result : { approved : boolean ; feedback ?: string } ) => void ;
78- const decisionPromise = new Promise < { approved : boolean ; feedback ?: string } > (
79- ( resolve ) => {
80- resolveDecision = resolve ;
81- }
82- ) ;
92+ let resolveDecision : ( result : {
93+ approved : boolean ;
94+ feedback ?: string ;
95+ savedPath ?: string ;
96+ } ) => void ;
97+ const decisionPromise = new Promise < {
98+ approved : boolean ;
99+ feedback ?: string ;
100+ savedPath ?: string ;
101+ } > ( ( resolve ) => {
102+ resolveDecision = resolve ;
103+ } ) ;
83104
84105 // Start server with retry logic
85106 let server : ReturnType < typeof Bun . serve > | null = null ;
@@ -183,25 +204,33 @@ export async function startPlannotatorServer(
183204 console . error ( `[Integration] Error:` , err ) ;
184205 }
185206
186- resolveDecision ( { approved : true , feedback } ) ;
187- return Response . json ( { ok : true } ) ;
207+ // Save annotations and final snapshot
208+ const diff = feedback || "" ;
209+ if ( diff ) {
210+ saveAnnotations ( slug , diff ) ;
211+ }
212+ const savedPath = saveFinalSnapshot ( slug , "approved" , plan , diff ) ;
213+
214+ resolveDecision ( { approved : true , feedback, savedPath } ) ;
215+ return Response . json ( { ok : true , savedPath } ) ;
188216 }
189217
190218 // API: Deny with feedback
191219 if ( url . pathname === "/api/deny" && req . method === "POST" ) {
220+ let feedback = "Plan rejected by user" ;
192221 try {
193222 const body = ( await req . json ( ) ) as { feedback ?: string } ;
194- resolveDecision ( {
195- approved : false ,
196- feedback : body . feedback || "Plan rejected by user" ,
197- } ) ;
223+ feedback = body . feedback || feedback ;
198224 } catch {
199- resolveDecision ( {
200- approved : false ,
201- feedback : "Plan rejected by user" ,
202- } ) ;
225+ // Use default feedback
203226 }
204- return Response . json ( { ok : true } ) ;
227+
228+ // Save annotations and final snapshot
229+ saveAnnotations ( slug , feedback ) ;
230+ const savedPath = saveFinalSnapshot ( slug , "denied" , plan , feedback ) ;
231+
232+ resolveDecision ( { approved : false , feedback, savedPath } ) ;
233+ return Response . json ( { ok : true , savedPath } ) ;
205234 }
206235
207236 // Serve embedded HTML for all other routes (SPA)
0 commit comments