@@ -306,6 +306,200 @@ describe("createMagicContextCommandHandler", () => {
306306 ) ;
307307 } ) ;
308308
309+ for ( const command of [ "ctx-wrapup" , "ctx-recomp" , "ctx-flush" ] as const ) {
310+ it ( `refuses /${ command } without side effects when compaction is off` , async ( ) => {
311+ insertTag ( db , "ses-compaction-off" , 1 , 500 ) ;
312+ insertPendingOp ( db , "ses-compaction-off" , 1 ) ;
313+ const sendNotification = mock ( async ( ) => { } ) ;
314+ const executeWrapup = mock ( async ( ) => "should not run" ) ;
315+ const executeRecomp = mock ( async ( ) => "should not run" ) ;
316+ const onFlush = mock ( ( ) => { } ) ;
317+ const handler = createMagicContextCommandHandler ( {
318+ db,
319+ protectedTags : 3 ,
320+ compactionOff : true ,
321+ executeWrapup,
322+ executeRecomp,
323+ onFlush,
324+ sendNotification,
325+ } ) ;
326+
327+ await expectSentinel (
328+ handler [ "command.execute.before" ] (
329+ { command, sessionID : "ses-compaction-off" , arguments : "" } ,
330+ makeOutput ( "" ) ,
331+ { } ,
332+ ) ,
333+ `__CONTEXT_MANAGEMENT_${ command . toUpperCase ( ) } _HANDLED__` ,
334+ ) ;
335+
336+ expect ( sendNotification ) . toHaveBeenCalledWith (
337+ "ses-compaction-off" ,
338+ `Magic Context compaction is disabled (compaction.enabled: false) — /${ command } manages compacted history and has no effect in this mode.` ,
339+ { } ,
340+ ) ;
341+ expect ( executeWrapup ) . not . toHaveBeenCalled ( ) ;
342+ expect ( executeRecomp ) . not . toHaveBeenCalled ( ) ;
343+ expect ( onFlush ) . not . toHaveBeenCalled ( ) ;
344+ expect ( getPendingOpsCount ( db , "ses-compaction-off" ) ) . toBe ( 1 ) ;
345+ expect ( getTagStatus ( db , "ses-compaction-off" , 1 ) ) . toBe ( "active" ) ;
346+ } ) ;
347+ }
348+
349+ it ( "keeps compaction commands functional when compaction is on" , async ( ) => {
350+ for ( const command of [ "ctx-wrapup" , "ctx-recomp" , "ctx-flush" ] as const ) {
351+ const sendNotification = mock ( async ( ) => { } ) ;
352+ const handler = createMagicContextCommandHandler ( {
353+ db,
354+ protectedTags : 3 ,
355+ compactionOff : false ,
356+ executeWrapup : async ( ) => "wrapup ran" ,
357+ executeRecomp : async ( ) => "recomp ran" ,
358+ sendNotification,
359+ } ) ;
360+
361+ await expectSentinel (
362+ handler [ "command.execute.before" ] (
363+ { command, sessionID : `ses-compaction-on-${ command } ` , arguments : "" } ,
364+ makeOutput ( "" ) ,
365+ { } ,
366+ ) ,
367+ `__CONTEXT_MANAGEMENT_${ command . toUpperCase ( ) } _HANDLED__` ,
368+ ) ;
369+
370+ const notifications = ( sendNotification . mock . calls as Array < [ string , string ] > ) . map (
371+ ( [ , text ] ) => text ,
372+ ) ;
373+ expect ( notifications . join ( "\n" ) ) . not . toContain ( "Magic Context compaction is disabled" ) ;
374+ }
375+ } ) ;
376+
377+ describe ( "knowledge-layer commands in compaction-off mode" , ( ) => {
378+ it ( "keeps /ctx-status functional and labels the mode" , async ( ) => {
379+ const sendNotification = mock ( async ( ) => { } ) ;
380+ const handler = createMagicContextCommandHandler ( {
381+ db,
382+ protectedTags : 3 ,
383+ compactionOff : true ,
384+ sendNotification,
385+ } ) ;
386+
387+ await expectSentinel (
388+ handler [ "command.execute.before" ] (
389+ { command : "ctx-status" , sessionID : "ses-status-off" , arguments : "" } ,
390+ makeOutput ( "" ) ,
391+ { } ,
392+ ) ,
393+ "__CONTEXT_MANAGEMENT_CTX-STATUS_HANDLED__" ,
394+ ) ;
395+
396+ expect ( sendNotification ) . toHaveBeenCalledWith (
397+ "ses-status-off" ,
398+ expect . stringContaining (
399+ "**Compaction:** disabled (compaction.enabled: false) — native compaction owns the context window." ,
400+ ) ,
401+ { } ,
402+ ) ;
403+ } ) ;
404+
405+ it ( "keeps /ctx-embed functional" , async ( ) => {
406+ const sendNotification = mock ( async ( ) => { } ) ;
407+ const handler = createMagicContextCommandHandler ( {
408+ db,
409+ protectedTags : 3 ,
410+ compactionOff : true ,
411+ getEmbedStatusText : ( ) => "embedding is ready" ,
412+ sendNotification,
413+ } ) ;
414+
415+ await expectSentinel (
416+ handler [ "command.execute.before" ] (
417+ { command : "ctx-embed" , sessionID : "ses-embed-off" , arguments : "" } ,
418+ makeOutput ( "" ) ,
419+ { } ,
420+ ) ,
421+ "__CONTEXT_MANAGEMENT_CTX-EMBED_HANDLED__" ,
422+ ) ;
423+
424+ expect ( sendNotification ) . toHaveBeenCalledWith (
425+ "ses-embed-off" ,
426+ "## Embedding Status\n\nembedding is ready" ,
427+ { } ,
428+ ) ;
429+ } ) ;
430+
431+ it ( "keeps /ctx-dream functional" , async ( ) => {
432+ const sendNotification = mock ( async ( ) => { } ) ;
433+ const runManual = mock ( async ( ) => ( {
434+ ran : [ "verify" ] ,
435+ skippedNoWork : [ ] ,
436+ deferredBusy : [ ] ,
437+ failed : [ ] ,
438+ } ) ) ;
439+ const handler = createMagicContextCommandHandler ( {
440+ db,
441+ protectedTags : 3 ,
442+ compactionOff : true ,
443+ sendNotification,
444+ dreamer : { config : { } as never , projectPath : "/repo" , runManual } ,
445+ } ) ;
446+
447+ await expectSentinel (
448+ handler [ "command.execute.before" ] (
449+ { command : "ctx-dream" , sessionID : "ses-dream-off" , arguments : "" } ,
450+ makeOutput ( "" ) ,
451+ { } ,
452+ ) ,
453+ "__CONTEXT_MANAGEMENT_CTX-DREAM_HANDLED__" ,
454+ ) ;
455+
456+ expect ( runManual ) . toHaveBeenCalledWith ( undefined ) ;
457+ } ) ;
458+
459+ it ( "keeps /ctx-aug functional" , async ( ) => {
460+ const sendNotification = mock ( async ( ) => { } ) ;
461+ const client = {
462+ session : {
463+ create : mock ( async ( ) => ( { data : { id : "sidekick-child" } } ) ) ,
464+ promptAsync : mock ( async ( ) => undefined ) ,
465+ messages : mock ( async ( ) => ( {
466+ data : [
467+ {
468+ info : { role : "assistant" , time : { created : Date . now ( ) } } ,
469+ parts : [ { type : "text" , text : "Use Bun" } ] ,
470+ } ,
471+ ] ,
472+ } ) ) ,
473+ delete : mock ( async ( ) => ( { data : undefined } ) ) ,
474+ } ,
475+ } ;
476+ const handler = createMagicContextCommandHandler ( {
477+ db,
478+ protectedTags : 3 ,
479+ compactionOff : true ,
480+ sendNotification,
481+ sidekick : {
482+ config : { timeout_ms : 5_000 } ,
483+ projectPath : "/repo" ,
484+ sessionDirectory : "/repo" ,
485+ client : client as never ,
486+ } ,
487+ } ) ;
488+
489+ await expectSentinel (
490+ handler [ "command.execute.before" ] (
491+ { command : "ctx-aug" , sessionID : "ses-aug-off" , arguments : "Check this" } ,
492+ makeOutput ( "" ) ,
493+ { } ,
494+ ) ,
495+ "__CONTEXT_MANAGEMENT_CTX-AUG_HANDLED__" ,
496+ ) ;
497+
498+ expect ( client . session . create ) . toHaveBeenCalledTimes ( 1 ) ;
499+ expect ( client . session . promptAsync ) . toHaveBeenCalledTimes ( 1 ) ;
500+ } ) ;
501+ } ) ;
502+
309503 describe ( "ctx-flush" , ( ) => {
310504 it ( "reports an empty queue" , async ( ) => {
311505 const sendNotification = mock ( async ( ) => { } ) ;
0 commit comments