@@ -8,7 +8,7 @@ import { CliError } from './errors';
88import { asRecord , pathExists } from './guards' ;
99import type { CollaborationProfile } from './collaboration' ;
1010import { validateSessionId } from './session' ;
11- import type { CliIO , UserIdentity } from './types' ;
11+ import type { CliIO , ExecutionMode , UserIdentity } from './types' ;
1212
1313const CONTEXT_VERSION = 'v1' ;
1414const ACTIVE_SESSION_FILENAME = 'active-session' ;
@@ -538,16 +538,44 @@ export async function clearContext(paths: ContextPaths): Promise<void> {
538538 await rm ( paths . contextDir , { recursive : true , force : true } ) ;
539539}
540540
541+ /**
542+ * Resolve the target session id for an operation, respecting execution mode.
543+ *
544+ * - If an explicit session id is provided, return it immediately.
545+ * - In host mode, an explicit session id is **required** — never fall back to
546+ * the project-global active-session file. This prevents cross-document
547+ * contamination between SDK clients sharing the same project root.
548+ * - In oneshot (CLI) mode, fall back to the active-session file as a
549+ * convenience for single-terminal workflows.
550+ */
551+ export async function resolveSessionId (
552+ sessionId : string | undefined ,
553+ executionMode : ExecutionMode | undefined ,
554+ ) : Promise < string > {
555+ if ( sessionId ) return sessionId ;
556+
557+ if ( executionMode === 'host' ) {
558+ throw new CliError (
559+ 'SESSION_REQUIRED' ,
560+ 'Host-mode operations require an explicit session id. Use the SDK document handle or pass --session.' ,
561+ ) ;
562+ }
563+
564+ const activeSessionId = await getActiveSessionId ( ) ;
565+ if ( ! activeSessionId ) {
566+ throw new CliError ( 'NO_ACTIVE_DOCUMENT' , 'No active document. Run "superdoc open <doc>" first.' ) ;
567+ }
568+ return activeSessionId ;
569+ }
570+
541571export async function withActiveContext < T > (
542572 io : CliIO ,
543573 command : string ,
544574 action : ( state : { metadata : ContextMetadata ; paths : ContextPaths } ) => Promise < T > ,
545575 contextId ?: string ,
576+ executionMode ?: ExecutionMode ,
546577) : Promise < T > {
547- const resolvedContextId = contextId ?? ( await getActiveSessionId ( ) ) ;
548- if ( ! resolvedContextId ) {
549- throw new CliError ( 'NO_ACTIVE_DOCUMENT' , 'No active document. Run "superdoc open <doc>" first.' ) ;
550- }
578+ const resolvedContextId = await resolveSessionId ( contextId , executionMode ) ;
551579
552580 return withContextLock (
553581 io ,
0 commit comments