diff --git a/blocksuite/affine/block-database/src/database-spec.ts b/blocksuite/affine/block-database/src/database-spec.ts
index 86edb47ce6024..c86ba5e1ed655 100644
--- a/blocksuite/affine/block-database/src/database-spec.ts
+++ b/blocksuite/affine/block-database/src/database-spec.ts
@@ -3,7 +3,6 @@ import {
   CommandExtension,
   FlavourExtension,
 } from '@blocksuite/block-std';
-import { DatabaseSelectionExtension } from '@blocksuite/data-view';
 import type { ExtensionType } from '@blocksuite/store';
 import { literal } from 'lit/static-html.js';
 
@@ -16,6 +15,5 @@ export const DatabaseBlockSpec: ExtensionType[] = [
   DatabaseBlockService,
   CommandExtension(commands),
   BlockViewExtension('affine:database', literal`affine-database`),
-  DatabaseSelectionExtension,
   DatabaseBlockAdapterExtensions,
 ].flat();
diff --git a/blocksuite/affine/block-image/src/components/page-image-block.ts b/blocksuite/affine/block-image/src/components/page-image-block.ts
index 8961bfd41f9cc..dc7b21b1bcb98 100644
--- a/blocksuite/affine/block-image/src/components/page-image-block.ts
+++ b/blocksuite/affine/block-image/src/components/page-image-block.ts
@@ -1,11 +1,12 @@
 import { ImageSelection } from '@blocksuite/affine-shared/selection';
-import type { BaseSelection, UIEventStateContext } from '@blocksuite/block-std';
+import type { UIEventStateContext } from '@blocksuite/block-std';
 import {
   BlockSelection,
   ShadowlessElement,
   TextSelection,
 } from '@blocksuite/block-std';
 import { WithDisposable } from '@blocksuite/global/utils';
+import type { BaseSelection } from '@blocksuite/store';
 import { css, html, type PropertyValues } from 'lit';
 import { property, query, state } from 'lit/decorators.js';
 import { styleMap } from 'lit/directives/style-map.js';
diff --git a/blocksuite/affine/block-image/src/image-spec.ts b/blocksuite/affine/block-image/src/image-spec.ts
index 92068953a3460..a1fbe453bf62e 100644
--- a/blocksuite/affine/block-image/src/image-spec.ts
+++ b/blocksuite/affine/block-image/src/image-spec.ts
@@ -1,4 +1,3 @@
-import { ImageSelectionExtension } from '@blocksuite/affine-shared/selection';
 import {
   BlockViewExtension,
   CommandExtension,
@@ -29,6 +28,5 @@ export const ImageBlockSpec: ExtensionType[] = [
     imageToolbar: literal`affine-image-toolbar-widget`,
   }),
   ImageDropOption,
-  ImageSelectionExtension,
   ImageBlockAdapterExtensions,
 ].flat();
diff --git a/blocksuite/affine/block-list/src/list-block.ts b/blocksuite/affine/block-list/src/list-block.ts
index 06396e97c6c5b..b6b5b36723eb1 100644
--- a/blocksuite/affine/block-list/src/list-block.ts
+++ b/blocksuite/affine/block-list/src/list-block.ts
@@ -14,13 +14,14 @@ import {
 } from '@blocksuite/affine-shared/consts';
 import { DocModeProvider } from '@blocksuite/affine-shared/services';
 import { getViewportElement } from '@blocksuite/affine-shared/utils';
-import type { BaseSelection, BlockComponent } from '@blocksuite/block-std';
+import type { BlockComponent } from '@blocksuite/block-std';
 import {
   BlockSelection,
   getInlineRangeProvider,
   TextSelection,
 } from '@blocksuite/block-std';
 import type { InlineRangeProvider } from '@blocksuite/inline';
+import type { BaseSelection } from '@blocksuite/store';
 import { effect } from '@preact/signals-core';
 import { html, nothing, type TemplateResult } from 'lit';
 import { query, state } from 'lit/decorators.js';
diff --git a/blocksuite/affine/block-note/src/note-service.ts b/blocksuite/affine/block-note/src/note-service.ts
index c17882c5e0157..3c9d9913e4bb2 100644
--- a/blocksuite/affine/block-note/src/note-service.ts
+++ b/blocksuite/affine/block-note/src/note-service.ts
@@ -2,7 +2,6 @@ import { textConversionConfigs } from '@blocksuite/affine-components/rich-text';
 import { NoteBlockSchema } from '@blocksuite/affine-model';
 import { matchFlavours } from '@blocksuite/affine-shared/utils';
 import {
-  type BaseSelection,
   type BlockComponent,
   BlockSelection,
   BlockService,
@@ -11,7 +10,7 @@ import {
   type UIEventHandler,
   type UIEventStateContext,
 } from '@blocksuite/block-std';
-import type { BlockModel } from '@blocksuite/store';
+import type { BaseSelection, BlockModel } from '@blocksuite/store';
 
 import { moveBlockConfigs } from './move-block';
 import { quickActionConfig } from './quick-action';
diff --git a/blocksuite/affine/block-surface-ref/src/surface-ref-block.ts b/blocksuite/affine/block-surface-ref/src/surface-ref-block.ts
index 8e12194916026..e3099aad33e23 100644
--- a/blocksuite/affine/block-surface-ref/src/surface-ref-block.ts
+++ b/blocksuite/affine/block-surface-ref/src/surface-ref-block.ts
@@ -26,7 +26,6 @@ import {
   SpecProvider,
 } from '@blocksuite/affine-shared/utils';
 import {
-  type BaseSelection,
   BlockComponent,
   BlockSelection,
   BlockServiceWatcher,
@@ -47,7 +46,7 @@ import {
   DisposableGroup,
   type SerializedXYWH,
 } from '@blocksuite/global/utils';
-import { type Store } from '@blocksuite/store';
+import type { BaseSelection, Store } from '@blocksuite/store';
 import { css, html, nothing, type TemplateResult } from 'lit';
 import { query, state } from 'lit/decorators.js';
 import { styleMap } from 'lit/directives/style-map.js';
diff --git a/blocksuite/affine/block-surface/src/surface-spec.ts b/blocksuite/affine/block-surface/src/surface-spec.ts
index 38e519cab4bef..acd639eda094d 100644
--- a/blocksuite/affine/block-surface/src/surface-spec.ts
+++ b/blocksuite/affine/block-surface/src/surface-spec.ts
@@ -1,4 +1,3 @@
-import { HighlightSelectionExtension } from '@blocksuite/affine-shared/selection';
 import {
   BlockViewExtension,
   CommandExtension,
@@ -23,7 +22,6 @@ const CommonSurfaceBlockSpec: ExtensionType[] = [
   FlavourExtension('affine:surface'),
   SurfaceBlockService,
   CommandExtension(commands),
-  HighlightSelectionExtension,
   MindMapView,
   EdgelessCRUDExtension,
   EdgelessLegacySlotExtension,
diff --git a/blocksuite/affine/data-view/src/core/common/selection-schema.ts b/blocksuite/affine/data-view/src/core/common/selection-schema.ts
index db6ee5bd567e4..76e0b90393db5 100644
--- a/blocksuite/affine/data-view/src/core/common/selection-schema.ts
+++ b/blocksuite/affine/data-view/src/core/common/selection-schema.ts
@@ -1,4 +1,4 @@
-import { BaseSelection, SelectionExtension } from '@blocksuite/block-std';
+import { BaseSelection, SelectionExtension } from '@blocksuite/store';
 import { z } from 'zod';
 
 import type { DataViewSelection, GetDataViewSelection } from '../types.js';
diff --git a/blocksuite/affine/shared/src/selection/hightlight.ts b/blocksuite/affine/shared/src/selection/hightlight.ts
index a4577c727695e..6af6fb016d0c2 100644
--- a/blocksuite/affine/shared/src/selection/hightlight.ts
+++ b/blocksuite/affine/shared/src/selection/hightlight.ts
@@ -2,7 +2,7 @@ import {
   type ReferenceParams,
   ReferenceParamsSchema,
 } from '@blocksuite/affine-model';
-import { BaseSelection, SelectionExtension } from '@blocksuite/block-std';
+import { BaseSelection, SelectionExtension } from '@blocksuite/store';
 
 export class HighlightSelection extends BaseSelection {
   static override group = 'scene';
diff --git a/blocksuite/affine/shared/src/selection/image.ts b/blocksuite/affine/shared/src/selection/image.ts
index 098c696f44150..f2b15a9a9cfcc 100644
--- a/blocksuite/affine/shared/src/selection/image.ts
+++ b/blocksuite/affine/shared/src/selection/image.ts
@@ -1,4 +1,4 @@
-import { BaseSelection, SelectionExtension } from '@blocksuite/block-std';
+import { BaseSelection, SelectionExtension } from '@blocksuite/store';
 import z from 'zod';
 
 const ImageSelectionSchema = z.object({
diff --git a/blocksuite/affine/widget-drag-handle/src/utils.ts b/blocksuite/affine/widget-drag-handle/src/utils.ts
index 16988a00ac31a..20a27f7db1ed2 100644
--- a/blocksuite/affine/widget-drag-handle/src/utils.ts
+++ b/blocksuite/affine/widget-drag-handle/src/utils.ts
@@ -9,13 +9,9 @@ import {
   getClosestBlockComponentByPoint,
   matchFlavours,
 } from '@blocksuite/affine-shared/utils';
-import type {
-  BaseSelection,
-  BlockComponent,
-  EditorHost,
-} from '@blocksuite/block-std';
+import type { BlockComponent, EditorHost } from '@blocksuite/block-std';
 import { Point, Rect } from '@blocksuite/global/utils';
-import type { BlockModel } from '@blocksuite/store';
+import type { BaseSelection, BlockModel } from '@blocksuite/store';
 
 import {
   DRAG_HANDLE_CONTAINER_HEIGHT,
diff --git a/blocksuite/affine/widget-remote-selection/src/doc/doc-remote-selection.ts b/blocksuite/affine/widget-remote-selection/src/doc/doc-remote-selection.ts
index e6a8e0597f80a..0df138b957e22 100644
--- a/blocksuite/affine/widget-remote-selection/src/doc/doc-remote-selection.ts
+++ b/blocksuite/affine/widget-remote-selection/src/doc/doc-remote-selection.ts
@@ -1,12 +1,11 @@
 import { matchFlavours } from '@blocksuite/affine-shared/utils';
 import {
-  type BaseSelection,
   BlockSelection,
   TextSelection,
   WidgetComponent,
 } from '@blocksuite/block-std';
 import { throttle } from '@blocksuite/global/utils';
-import type { UserInfo } from '@blocksuite/store';
+import type { BaseSelection, UserInfo } from '@blocksuite/store';
 import { computed, effect } from '@preact/signals-core';
 import { css, html, nothing, type PropertyValues } from 'lit';
 import { state } from 'lit/decorators.js';
diff --git a/blocksuite/blocks/src/_specs/common.ts b/blocksuite/blocks/src/_specs/common.ts
index a814060a4a414..24e556f486b6c 100644
--- a/blocksuite/blocks/src/_specs/common.ts
+++ b/blocksuite/blocks/src/_specs/common.ts
@@ -27,6 +27,10 @@ import {
   RefNodeSlotsExtension,
   RichTextExtensions,
 } from '@blocksuite/affine-components/rich-text';
+import {
+  HighlightSelectionExtension,
+  ImageSelectionExtension,
+} from '@blocksuite/affine-shared/selection';
 import {
   DefaultOpenDocExtension,
   DocDisplayMetaService,
@@ -34,6 +38,13 @@ import {
   FeatureFlagService,
   FontLoaderService,
 } from '@blocksuite/affine-shared/services';
+import {
+  BlockSelectionExtension,
+  CursorSelectionExtension,
+  SurfaceSelectionExtension,
+  TextSelectionExtension,
+} from '@blocksuite/block-std';
+import { DatabaseSelectionExtension } from '@blocksuite/data-view';
 import type { ExtensionType } from '@blocksuite/store';
 
 import { AdapterFactoryExtensions } from '../_common/adapters/extension.js';
@@ -77,4 +88,13 @@ export const EdgelessFirstPartyBlockSpecs: ExtensionType[] = [
   FontLoaderService,
 ].flat();
 
-export const StoreExtensions: ExtensionType[] = [FeatureFlagService];
+export const StoreExtensions: ExtensionType[] = [
+  FeatureFlagService,
+  BlockSelectionExtension,
+  TextSelectionExtension,
+  SurfaceSelectionExtension,
+  CursorSelectionExtension,
+  HighlightSelectionExtension,
+  ImageSelectionExtension,
+  DatabaseSelectionExtension,
+];
diff --git a/blocksuite/blocks/src/root-block/widgets/ai-panel/ai-panel.ts b/blocksuite/blocks/src/root-block/widgets/ai-panel/ai-panel.ts
index 028fa6be31831..257ace28ad47a 100644
--- a/blocksuite/blocks/src/root-block/widgets/ai-panel/ai-panel.ts
+++ b/blocksuite/blocks/src/root-block/widgets/ai-panel/ai-panel.ts
@@ -7,9 +7,9 @@ import {
   getPageRootByElement,
   stopPropagation,
 } from '@blocksuite/affine-shared/utils';
-import type { BaseSelection } from '@blocksuite/block-std';
 import { WidgetComponent } from '@blocksuite/block-std';
 import { assertExists } from '@blocksuite/global/utils';
+import type { BaseSelection } from '@blocksuite/store';
 import {
   autoPlacement,
   autoUpdate,
diff --git a/blocksuite/blocks/src/root-block/widgets/format-bar/format-bar.ts b/blocksuite/blocks/src/root-block/widgets/format-bar/format-bar.ts
index 4d373903e9171..8d455afa09edb 100644
--- a/blocksuite/blocks/src/root-block/widgets/format-bar/format-bar.ts
+++ b/blocksuite/blocks/src/root-block/widgets/format-bar/format-bar.ts
@@ -9,7 +9,6 @@ import {
 import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
 import { matchFlavours } from '@blocksuite/affine-shared/utils';
 import {
-  type BaseSelection,
   type BlockComponent,
   BlockSelection,
   CursorSelection,
@@ -22,6 +21,7 @@ import {
   DisposableGroup,
   nextTick,
 } from '@blocksuite/global/utils';
+import type { BaseSelection } from '@blocksuite/store';
 import {
   autoUpdate,
   computePosition,
diff --git a/blocksuite/framework/block-std/src/extension/index.ts b/blocksuite/framework/block-std/src/extension/index.ts
index 8171ad221cde4..20f94f8308ed2 100644
--- a/blocksuite/framework/block-std/src/extension/index.ts
+++ b/blocksuite/framework/block-std/src/extension/index.ts
@@ -4,7 +4,6 @@ export * from './config.js';
 export * from './flavour.js';
 export * from './keymap.js';
 export * from './lifecycle-watcher.js';
-export * from './selection.js';
 export * from './service.js';
 export * from './service-watcher.js';
 export * from './widget-view-map.js';
diff --git a/blocksuite/framework/block-std/src/extension/selection.ts b/blocksuite/framework/block-std/src/extension/selection.ts
deleted file mode 100644
index 33162c92b6e9a..0000000000000
--- a/blocksuite/framework/block-std/src/extension/selection.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import type { ExtensionType } from '@blocksuite/store';
-
-import { SelectionIdentifier } from '../identifier.js';
-import type { SelectionConstructor } from '../selection/index.js';
-
-export function SelectionExtension(
-  selectionCtor: SelectionConstructor
-): ExtensionType {
-  return {
-    setup: di => {
-      di.addImpl(SelectionIdentifier(selectionCtor.type), () => selectionCtor);
-    },
-  };
-}
diff --git a/blocksuite/framework/block-std/src/identifier.ts b/blocksuite/framework/block-std/src/identifier.ts
index 4adf0e4d2d853..571d509c3839f 100644
--- a/blocksuite/framework/block-std/src/identifier.ts
+++ b/blocksuite/framework/block-std/src/identifier.ts
@@ -4,7 +4,6 @@ import type { Command } from './command/index.js';
 import type { EventOptions, UIEventHandler } from './event/index.js';
 import type { BlockService, LifeCycleWatcher } from './extension/index.js';
 import type { BlockStdScope } from './scope/index.js';
-import type { SelectionConstructor } from './selection/index.js';
 import type { BlockViewType, WidgetViewMapType } from './spec/type.js';
 
 export const BlockServiceIdentifier =
@@ -33,6 +32,3 @@ export const KeymapIdentifier = createIdentifier<{
   getter: (std: BlockStdScope) => Record<string, UIEventHandler>;
   options?: EventOptions;
 }>('Keymap');
-
-export const SelectionIdentifier =
-  createIdentifier<SelectionConstructor>('Selection');
diff --git a/blocksuite/framework/block-std/src/range/inline-range-provider.ts b/blocksuite/framework/block-std/src/range/inline-range-provider.ts
index 90280f9daed57..5466d0fa964e8 100644
--- a/blocksuite/framework/block-std/src/range/inline-range-provider.ts
+++ b/blocksuite/framework/block-std/src/range/inline-range-provider.ts
@@ -84,18 +84,21 @@ export const getInlineRangeProvider: (
     }
   };
   const inlineRange$: InlineRangeProvider['inlineRange$'] = signal(null);
-  selectionManager.slots.changed.on(selections => {
-    const textSelection = selections.find(s => s.type === 'text') as
-      | TextSelection
-      | undefined;
-    const range = rangeManager.value;
-    if (!range || !textSelection) {
-      inlineRange$.value = null;
-      return;
-    }
-    const inlineRange = calculateInlineRange(range, textSelection);
-    inlineRange$.value = inlineRange;
-  });
+
+  editorHost.disposables.add(
+    selectionManager.slots.changed.on(selections => {
+      const textSelection = selections.find(s => s.type === 'text') as
+        | TextSelection
+        | undefined;
+      const range = rangeManager.value;
+      if (!range || !textSelection) {
+        inlineRange$.value = null;
+        return;
+      }
+      const inlineRange = calculateInlineRange(range, textSelection);
+      inlineRange$.value = inlineRange;
+    })
+  );
 
   return {
     setInlineRange,
diff --git a/blocksuite/framework/block-std/src/range/range-binding.ts b/blocksuite/framework/block-std/src/range/range-binding.ts
index 8095d778c2ba5..b3eee6ff2ae13 100644
--- a/blocksuite/framework/block-std/src/range/range-binding.ts
+++ b/blocksuite/framework/block-std/src/range/range-binding.ts
@@ -1,7 +1,7 @@
 import { throttle } from '@blocksuite/global/utils';
-import type { BlockModel } from '@blocksuite/store';
+import type { BaseSelection, BlockModel } from '@blocksuite/store';
 
-import { type BaseSelection, TextSelection } from '../selection/index.js';
+import { TextSelection } from '../selection/index.js';
 import type { BlockComponent } from '../view/element/block-component.js';
 import { BLOCK_ID_ATTR } from '../view/index.js';
 import { RANGE_SYNC_EXCLUDE_ATTR } from './consts.js';
@@ -247,6 +247,9 @@ export class RangeBinding {
   };
 
   private readonly _onStdSelectionChanged = (selections: BaseSelection[]) => {
+    const closestHost = document.activeElement?.closest('editor-host');
+    if (closestHost && closestHost !== this.host) return;
+
     const text =
       selections.find((selection): selection is TextSelection =>
         selection.is(TextSelection)
diff --git a/blocksuite/framework/block-std/src/scope/block-std-scope.ts b/blocksuite/framework/block-std/src/scope/block-std-scope.ts
index 2019f13e21401..ba220fb61777b 100644
--- a/blocksuite/framework/block-std/src/scope/block-std-scope.ts
+++ b/blocksuite/framework/block-std/src/scope/block-std-scope.ts
@@ -5,6 +5,7 @@ import {
   Job,
   type JobMiddleware,
   type Store,
+  StoreSelectionExtension,
 } from '@blocksuite/store';
 
 import { Clipboard } from '../clipboard/index.js';
@@ -23,13 +24,6 @@ import {
   StdIdentifier,
 } from '../identifier.js';
 import { RangeManager } from '../range/index.js';
-import {
-  BlockSelectionExtension,
-  CursorSelectionExtension,
-  SelectionManager,
-  SurfaceSelectionExtension,
-  TextSelectionExtension,
-} from '../selection/index.js';
 import { ServiceManager } from '../service/index.js';
 import { EditorHost } from '../view/element/index.js';
 import { ViewStore } from '../view/view-store.js';
@@ -43,15 +37,10 @@ const internalExtensions = [
   ServiceManager,
   CommandManager,
   UIEventDispatcher,
-  SelectionManager,
   RangeManager,
   ViewStore,
   Clipboard,
   GfxController,
-  BlockSelectionExtension,
-  TextSelectionExtension,
-  SurfaceSelectionExtension,
-  CursorSelectionExtension,
   GfxSelectionManager,
   SurfaceMiddlewareExtension,
   ViewManager,
@@ -107,7 +96,7 @@ export class BlockStdScope {
   }
 
   get selection() {
-    return this.get(SelectionManager);
+    return this.get(StoreSelectionExtension);
   }
 
   get view() {
diff --git a/blocksuite/framework/block-std/src/selection/index.ts b/blocksuite/framework/block-std/src/selection/index.ts
index cdb6841fb72bd..8ac7bfc5bc4d1 100644
--- a/blocksuite/framework/block-std/src/selection/index.ts
+++ b/blocksuite/framework/block-std/src/selection/index.ts
@@ -1,3 +1 @@
-export * from './base.js';
-export * from './manager.js';
 export * from './variants/index.js';
diff --git a/blocksuite/framework/block-std/src/selection/variants/block.ts b/blocksuite/framework/block-std/src/selection/variants/block.ts
index dbd75a28ec3f0..765ec2a319f56 100644
--- a/blocksuite/framework/block-std/src/selection/variants/block.ts
+++ b/blocksuite/framework/block-std/src/selection/variants/block.ts
@@ -1,8 +1,6 @@
+import { BaseSelection, SelectionExtension } from '@blocksuite/store';
 import z from 'zod';
 
-import { SelectionExtension } from '../../extension/selection.js';
-import { BaseSelection } from '../base.js';
-
 const BlockSelectionSchema = z.object({
   blockId: z.string(),
 });
diff --git a/blocksuite/framework/block-std/src/selection/variants/cursor.ts b/blocksuite/framework/block-std/src/selection/variants/cursor.ts
index a6ede90552c3c..9c7d56559e5c7 100644
--- a/blocksuite/framework/block-std/src/selection/variants/cursor.ts
+++ b/blocksuite/framework/block-std/src/selection/variants/cursor.ts
@@ -1,8 +1,6 @@
+import { BaseSelection, SelectionExtension } from '@blocksuite/store';
 import z from 'zod';
 
-import { SelectionExtension } from '../../extension/selection.js';
-import { BaseSelection } from '../base.js';
-
 const CursorSelectionSchema = z.object({
   x: z.number(),
   y: z.number(),
diff --git a/blocksuite/framework/block-std/src/selection/variants/surface.ts b/blocksuite/framework/block-std/src/selection/variants/surface.ts
index 1fe7092e81817..60d9c8e0744db 100644
--- a/blocksuite/framework/block-std/src/selection/variants/surface.ts
+++ b/blocksuite/framework/block-std/src/selection/variants/surface.ts
@@ -1,8 +1,6 @@
+import { BaseSelection, SelectionExtension } from '@blocksuite/store';
 import z from 'zod';
 
-import { SelectionExtension } from '../../extension/selection.js';
-import { BaseSelection } from '../base.js';
-
 const SurfaceSelectionSchema = z.object({
   blockId: z.string(),
   elements: z.array(z.string()),
diff --git a/blocksuite/framework/block-std/src/selection/variants/text.ts b/blocksuite/framework/block-std/src/selection/variants/text.ts
index 29217ead00940..e88c1fd3ae171 100644
--- a/blocksuite/framework/block-std/src/selection/variants/text.ts
+++ b/blocksuite/framework/block-std/src/selection/variants/text.ts
@@ -1,8 +1,6 @@
+import { BaseSelection, SelectionExtension } from '@blocksuite/store';
 import z from 'zod';
 
-import { SelectionExtension } from '../../extension/selection.js';
-import { BaseSelection } from '../base.js';
-
 export type TextRangePoint = {
   blockId: string;
   index: number;
diff --git a/blocksuite/framework/block-std/src/view/element/lit-host.ts b/blocksuite/framework/block-std/src/view/element/lit-host.ts
index fbe660e006e8d..bd90704f9e68a 100644
--- a/blocksuite/framework/block-std/src/view/element/lit-host.ts
+++ b/blocksuite/framework/block-std/src/view/element/lit-host.ts
@@ -4,7 +4,11 @@ import {
   handleError,
 } from '@blocksuite/global/exceptions';
 import { SignalWatcher, Slot, WithDisposable } from '@blocksuite/global/utils';
-import { type BlockModel, Store } from '@blocksuite/store';
+import {
+  type BlockModel,
+  Store,
+  type StoreSelectionExtension,
+} from '@blocksuite/store';
 import { createContext, provide } from '@lit/context';
 import { css, LitElement, nothing, type TemplateResult } from 'lit';
 import { property } from 'lit/decorators.js';
@@ -16,7 +20,6 @@ import type { UIEventDispatcher } from '../../event/index.js';
 import { WidgetViewMapIdentifier } from '../../identifier.js';
 import type { RangeManager } from '../../range/index.js';
 import type { BlockStdScope } from '../../scope/block-std-scope.js';
-import type { SelectionManager } from '../../selection/index.js';
 import { PropTypes, requiredProperties } from '../decorators/index.js';
 import type { ViewStore } from '../view-store.js';
 import { BLOCK_ID_ATTR, WIDGET_ID_ATTR } from './consts.js';
@@ -114,7 +117,7 @@ export class EditorHost extends SignalWatcher(
     return this.std.range;
   }
 
-  get selection(): SelectionManager {
+  get selection(): StoreSelectionExtension {
     return this.std.selection;
   }
 
diff --git a/blocksuite/framework/store/src/extension/index.ts b/blocksuite/framework/store/src/extension/index.ts
index 8b7ae56bdbe1c..554a044e137e5 100644
--- a/blocksuite/framework/store/src/extension/index.ts
+++ b/blocksuite/framework/store/src/extension/index.ts
@@ -1,2 +1,3 @@
 export * from './extension';
+export * from './selection';
 export * from './store-extension';
diff --git a/blocksuite/framework/block-std/src/selection/base.ts b/blocksuite/framework/store/src/extension/selection/base.ts
similarity index 94%
rename from blocksuite/framework/block-std/src/selection/base.ts
rename to blocksuite/framework/store/src/extension/selection/base.ts
index b2433ccbbd382..52a8f84e5c485 100644
--- a/blocksuite/framework/block-std/src/selection/base.ts
+++ b/blocksuite/framework/store/src/extension/selection/base.ts
@@ -1,6 +1,6 @@
 import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
 
-import type { SelectionConstructor } from './manager';
+import type { SelectionConstructor } from './types';
 
 export type BaseSelectionOptions = {
   blockId: string;
diff --git a/blocksuite/framework/store/src/extension/selection/identifier.ts b/blocksuite/framework/store/src/extension/selection/identifier.ts
new file mode 100644
index 0000000000000..24f9fdff38475
--- /dev/null
+++ b/blocksuite/framework/store/src/extension/selection/identifier.ts
@@ -0,0 +1,17 @@
+import { createIdentifier } from '@blocksuite/global/di';
+
+import type { ExtensionType } from '../extension';
+import type { SelectionConstructor } from './types';
+
+export const SelectionIdentifier =
+  createIdentifier<SelectionConstructor>('Selection');
+
+export function SelectionExtension(
+  selectionCtor: SelectionConstructor
+): ExtensionType {
+  return {
+    setup: di => {
+      di.addImpl(SelectionIdentifier(selectionCtor.type), () => selectionCtor);
+    },
+  };
+}
diff --git a/blocksuite/framework/store/src/extension/selection/index.ts b/blocksuite/framework/store/src/extension/selection/index.ts
new file mode 100644
index 0000000000000..aabfea3569f34
--- /dev/null
+++ b/blocksuite/framework/store/src/extension/selection/index.ts
@@ -0,0 +1,4 @@
+export * from './base';
+export * from './identifier';
+export * from './selection-extension';
+export * from './types';
diff --git a/blocksuite/framework/block-std/src/selection/manager.ts b/blocksuite/framework/store/src/extension/selection/selection-extension.ts
similarity index 62%
rename from blocksuite/framework/block-std/src/selection/manager.ts
rename to blocksuite/framework/store/src/extension/selection/selection-extension.ts
index 9145f87453c58..258141c1f61f2 100644
--- a/blocksuite/framework/block-std/src/selection/manager.ts
+++ b/blocksuite/framework/store/src/extension/selection/selection-extension.ts
@@ -1,28 +1,27 @@
 import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
-import { DisposableGroup, Slot } from '@blocksuite/global/utils';
-import { nanoid, type StackItem } from '@blocksuite/store';
+import { Slot } from '@blocksuite/global/utils';
 import { computed, signal } from '@preact/signals-core';
 
-import { LifeCycleWatcher } from '../extension/index.js';
-import { SelectionIdentifier } from '../identifier.js';
-import type { BlockStdScope } from '../scope/index.js';
-import type { BaseSelection } from './base.js';
+import type { Store } from '../../model';
+import { nanoid } from '../../utils/id-generator';
+import type { StackItem } from '../../yjs';
+import { StoreExtension } from '../store-extension';
+import type { BaseSelection } from './base';
+import { SelectionIdentifier } from './identifier';
+import type { SelectionConstructor } from './types';
 
-export interface SelectionConstructor<T extends BaseSelection = BaseSelection> {
-  type: string;
-  group: string;
+export class StoreSelectionExtension extends StoreExtension {
+  static override readonly key = 'selection';
 
-  new (...args: any[]): T;
-  fromJSON(json: Record<string, unknown>): T;
-}
-
-export class SelectionManager extends LifeCycleWatcher {
-  static override readonly key = 'selectionManager';
-
-  private readonly _id: string;
+  private readonly _id = `${this.store.id}:${nanoid()}`;
+  private _selectionConstructors: Record<string, SelectionConstructor> = {};
+  private readonly _selections = signal<BaseSelection[]>([]);
+  private readonly _remoteSelections = signal<Map<number, BaseSelection[]>>(
+    new Map()
+  );
 
   private readonly _itemAdded = (event: { stackItem: StackItem }) => {
-    event.stackItem.meta.set('selection-state', this.value);
+    event.stackItem.meta.set('selection-state', this._selections.value);
   };
 
   private readonly _itemPopped = (event: { stackItem: StackItem }) => {
@@ -43,50 +42,30 @@ export class SelectionManager extends LifeCycleWatcher {
     return ctor.fromJSON(json);
   };
 
-  private readonly _remoteSelections = signal<Map<number, BaseSelection[]>>(
-    new Map()
-  );
-
-  private _selectionConstructors: Record<string, SelectionConstructor> = {};
-
-  private readonly _selections = signal<BaseSelection[]>([]);
-
-  disposables = new DisposableGroup();
-
   slots = {
     changed: new Slot<BaseSelection[]>(),
     remoteChanged: new Slot<Map<number, BaseSelection[]>>(),
   };
 
-  private get _store() {
-    return this.std.workspace.awarenessStore;
-  }
-
-  get id() {
-    return this._id;
-  }
-
-  get remoteSelections() {
-    return this._remoteSelections.value;
-  }
+  constructor(store: Store) {
+    super(store);
 
-  get value() {
-    return this._selections.value;
-  }
+    this.store.provider.getAll(SelectionIdentifier).forEach(ctor => {
+      [ctor].flat().forEach(ctor => {
+        this._selectionConstructors[ctor.type] = ctor;
+      });
+    });
 
-  constructor(std: BlockStdScope) {
-    super(std);
-    this._id = `${this.std.store.id}:${nanoid()}`;
-    this._setupDefaultSelections();
-    this._store.awareness.on(
+    this.store.awarenessStore.awareness.on(
       'change',
       (change: { updated: number[]; added: number[]; removed: number[] }) => {
         const all = change.updated.concat(change.added).concat(change.removed);
-        const localClientID = this._store.awareness.clientID;
+        const localClientID = this.store.awarenessStore.awareness.clientID;
         const exceptLocal = all.filter(id => id !== localClientID);
         const hasLocal = all.includes(localClientID);
         if (hasLocal) {
-          const localSelectionJson = this._store.getLocalSelection(this.id);
+          const localSelectionJson =
+            this.store.awarenessStore.getLocalSelection(this._id);
           const localSelection = localSelectionJson.map(json => {
             return this._jsonToSelection(json);
           });
@@ -96,11 +75,11 @@ export class SelectionManager extends LifeCycleWatcher {
         // Only consider remote selections from other clients
         if (exceptLocal.length > 0) {
           const map = new Map<number, BaseSelection[]>();
-          this._store.getStates().forEach((state, id) => {
-            if (id === this._store.awareness.clientID) return;
+          this.store.awarenessStore.getStates().forEach((state, id) => {
+            if (id === this.store.awarenessStore.awareness.clientID) return;
             // selection id starts with the same block collection id from others clients would be considered as remote selections
             const selection = Object.entries(state.selectionV2)
-              .filter(([key]) => key.startsWith(this.std.store.id))
+              .filter(([key]) => key.startsWith(this.store.id))
               .flatMap(([_, selection]) => selection);
 
             const selections = selection
@@ -122,15 +101,21 @@ export class SelectionManager extends LifeCycleWatcher {
             map.set(id, selections);
           });
           this._remoteSelections.value = map;
+          this.slots.remoteChanged.emit(map);
         }
       }
     );
+
+    this.store.history.on('stack-item-added', this._itemAdded);
+    this.store.history.on('stack-item-popped', this._itemPopped);
   }
 
-  private _setupDefaultSelections() {
-    this.std.provider.getAll(SelectionIdentifier).forEach(ctor => {
-      this.register(ctor);
-    });
+  get value() {
+    return this._selections.value;
+  }
+
+  get remoteSelections() {
+    return this._remoteSelections.value;
   }
 
   clear(types?: string[]) {
@@ -151,9 +136,8 @@ export class SelectionManager extends LifeCycleWatcher {
     return new Type(...args) as InstanceType<T>;
   }
 
-  dispose() {
-    Object.values(this.slots).forEach(slot => slot.dispose());
-    this.disposables.dispose();
+  getGroup(group: string) {
+    return this.value.filter(s => s.group === group);
   }
 
   filter<T extends SelectionConstructor>(type: T) {
@@ -176,43 +160,9 @@ export class SelectionManager extends LifeCycleWatcher {
     );
   }
 
-  fromJSON(json: Record<string, unknown>[]) {
-    const selections = json.map(json => {
-      return this._jsonToSelection(json);
-    });
-    return this.set(selections);
-  }
-
-  getGroup(group: string) {
-    return this.value.filter(s => s.group === group);
-  }
-
-  override mounted() {
-    if (this.disposables.disposed) {
-      this.disposables = new DisposableGroup();
-    }
-    this.std.store.history.on('stack-item-added', this._itemAdded);
-    this.std.store.history.on('stack-item-popped', this._itemPopped);
-    this.disposables.add(
-      this._store.slots.update.on(({ id }) => {
-        if (id === this._store.awareness.clientID) {
-          return;
-        }
-        this.slots.remoteChanged.emit(this.remoteSelections);
-      })
-    );
-  }
-
-  register(ctor: SelectionConstructor | SelectionConstructor[]) {
-    [ctor].flat().forEach(ctor => {
-      this._selectionConstructors[ctor.type] = ctor;
-    });
-    return this;
-  }
-
   set(selections: BaseSelection[]) {
-    this._store.setLocalSelection(
-      this.id,
+    this.store.awarenessStore.setLocalSelection(
+      this._id,
       selections.map(s => s.toJSON())
     );
     this.slots.changed.emit(selections);
@@ -223,16 +173,15 @@ export class SelectionManager extends LifeCycleWatcher {
     this.set([...current, ...selections]);
   }
 
-  override unmounted() {
-    this.std.store.history.off('stack-item-added', this._itemAdded);
-    this.std.store.history.off('stack-item-popped', this._itemPopped);
-    this.slots.changed.dispose();
-    this.disposables.dispose();
-    this.clear();
-  }
-
   update(fn: (currentSelections: BaseSelection[]) => BaseSelection[]) {
     const selections = fn(this.value);
     this.set(selections);
   }
+
+  fromJSON(json: Record<string, unknown>[]) {
+    const selections = json.map(json => {
+      return this._jsonToSelection(json);
+    });
+    return this.set(selections);
+  }
 }
diff --git a/blocksuite/framework/store/src/extension/selection/types.ts b/blocksuite/framework/store/src/extension/selection/types.ts
new file mode 100644
index 0000000000000..eea8b6c544d25
--- /dev/null
+++ b/blocksuite/framework/store/src/extension/selection/types.ts
@@ -0,0 +1,9 @@
+import type { BaseSelection } from './base';
+
+export interface SelectionConstructor<T extends BaseSelection = BaseSelection> {
+  type: string;
+  group: string;
+
+  new (...args: any[]): T;
+  fromJSON(json: Record<string, unknown>): T;
+}
diff --git a/blocksuite/framework/store/src/model/store/store.ts b/blocksuite/framework/store/src/model/store/store.ts
index 2f028aba920f0..cc10aed1aec3f 100644
--- a/blocksuite/framework/store/src/model/store/store.ts
+++ b/blocksuite/framework/store/src/model/store/store.ts
@@ -4,6 +4,7 @@ import { type Disposable, Slot } from '@blocksuite/global/utils';
 import { signal } from '@preact/signals-core';
 
 import type { ExtensionType } from '../../extension/extension.js';
+import { StoreSelectionExtension } from '../../extension/index.js';
 import type { Schema } from '../../schema/index.js';
 import {
   Block,
@@ -27,29 +28,33 @@ export type StoreOptions = {
   extensions?: ExtensionType[];
 };
 
+const internalExtensions = [StoreSelectionExtension];
+
 export class Store {
+  readonly userExtensions: ExtensionType[];
+
   private readonly _provider: ServiceProvider;
 
   private readonly _runQuery = (block: Block) => {
     runQuery(this._query, block);
   };
 
-  protected readonly _doc: Doc;
+  private readonly _doc: Doc;
 
-  protected readonly _blocks = signal<Record<string, Block>>({});
+  private readonly _blocks = signal<Record<string, Block>>({});
 
-  protected readonly _crud: DocCRUD;
+  private readonly _crud: DocCRUD;
 
-  protected readonly _disposeBlockUpdated: Disposable;
+  private readonly _disposeBlockUpdated: Disposable;
 
-  protected readonly _query: Query = {
+  private readonly _query: Query = {
     match: [],
     mode: 'loose',
   };
 
-  protected _readonly = signal(false);
+  private readonly _readonly = signal(false);
 
-  protected readonly _schema: Schema;
+  private readonly _schema: Schema;
 
   readonly slots: Doc['slots'] & {
     /** This is always triggered after `doc.load` is called. */
@@ -295,7 +300,12 @@ export class Store {
     const container = new Container();
     container.addImpl(StoreIdentifier, () => this);
 
+    internalExtensions.forEach(ext => {
+      ext.setup(container);
+    });
+
     const userExtensions = extensions ?? [];
+    this.userExtensions = userExtensions;
     userExtensions.forEach(extension => {
       extension.setup(container);
     });
diff --git a/blocksuite/presets/src/__tests__/utils/setup.ts b/blocksuite/presets/src/__tests__/utils/setup.ts
index bee73f382fe41..9c2066ececc94 100644
--- a/blocksuite/presets/src/__tests__/utils/setup.ts
+++ b/blocksuite/presets/src/__tests__/utils/setup.ts
@@ -9,8 +9,8 @@ effects();
 import {
   CommunityCanvasTextFonts,
   type DocMode,
-  FeatureFlagService,
   FontConfigExtension,
+  StoreExtensions,
 } from '@blocksuite/blocks';
 import { AffineSchemas } from '@blocksuite/blocks/schemas';
 import { assertExists } from '@blocksuite/global/utils';
@@ -85,7 +85,7 @@ async function createEditor(collection: TestWorkspace, mode: DocMode = 'page') {
 
 export async function setupEditor(mode: DocMode = 'page') {
   const collection = new TestWorkspace(createCollectionOptions());
-  collection.storeExtensions = [FeatureFlagService];
+  collection.storeExtensions = StoreExtensions;
   collection.meta.initialize();
 
   window.collection = collection;
diff --git a/blocksuite/tests-legacy/edgeless/note/note.spec.ts b/blocksuite/tests-legacy/edgeless/note/note.spec.ts
index d1c092ba0a618..f8b8de7c8da8f 100644
--- a/blocksuite/tests-legacy/edgeless/note/note.spec.ts
+++ b/blocksuite/tests-legacy/edgeless/note/note.spec.ts
@@ -329,7 +329,6 @@ test('cursor for active and inactive state', async ({ page }) => {
 
   await switchEditorMode(page);
 
-  await assertTextSelection(page);
   await page.mouse.click(CENTER_X, CENTER_Y);
   await waitNextFrame(page);
   await assertTextSelection(page);
diff --git a/blocksuite/tests-legacy/edgeless/paste-block.spec.ts b/blocksuite/tests-legacy/edgeless/paste-block.spec.ts
index 1813e62f97864..69b7cd5ce35c2 100644
--- a/blocksuite/tests-legacy/edgeless/paste-block.spec.ts
+++ b/blocksuite/tests-legacy/edgeless/paste-block.spec.ts
@@ -43,6 +43,7 @@ test.describe('pasting blocks', () => {
     await focusRichText(page);
     await initContent(page);
     await switchEditorMode(page);
+    await click(page, { x: 0, y: 0 });
     const box = await getNoteBoundBoxInEdgeless(page, noteId);
     await click(page, {
       x: box.x + 10,
diff --git a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-panel-messages.ts b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-panel-messages.ts
index b2b578f098848..543c7e4def11a 100644
--- a/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-panel-messages.ts
+++ b/packages/frontend/core/src/blocksuite/presets/ai/chat-panel/chat-panel-messages.ts
@@ -1,4 +1,4 @@
-import type { BaseSelection, EditorHost } from '@blocksuite/affine/block-std';
+import type { EditorHost } from '@blocksuite/affine/block-std';
 import { ShadowlessElement } from '@blocksuite/affine/block-std';
 import {
   type AIError,
@@ -9,6 +9,7 @@ import {
   UnauthorizedError,
 } from '@blocksuite/affine/blocks';
 import { WithDisposable } from '@blocksuite/affine/global/utils';
+import type { BaseSelection } from '@blocksuite/affine/store';
 import { css, html, nothing } from 'lit';
 import { property, query, state } from 'lit/decorators.js';
 import { repeat } from 'lit/directives/repeat.js';
diff --git a/tests/affine-local/e2e/links.spec.ts b/tests/affine-local/e2e/links.spec.ts
index b8b28e9443f21..949f1e5a761bf 100644
--- a/tests/affine-local/e2e/links.spec.ts
+++ b/tests/affine-local/e2e/links.spec.ts
@@ -62,6 +62,7 @@ test('not allowed to switch to embed view when linking to the same document', as
   await expect(peekViewModel.locator('page-editor')).toBeVisible();
   await page.keyboard.press('Escape');
   await expect(peekViewModel).not.toBeVisible();
+  await page.click('body');
 
   await cardLink.click();
   await cardToolbar.getByLabel('Switch view').click();
@@ -103,6 +104,7 @@ test('not allowed to switch to embed view when linking to block', async ({
   await page.keyboard.press('Escape');
   await expect(peekViewModel).not.toBeVisible();
 
+  await page.click('body');
   await cardLink.click();
 
   await cardToolbar.getByLabel('More').click();
@@ -131,6 +133,7 @@ test('not allowed to switch to embed view when linking to block', async ({
   await page.keyboard.press('Escape');
   await expect(peekViewModel).not.toBeVisible();
 
+  await page.click('body');
   await otherCardLink.click();
   await cardToolbar.getByLabel('Switch view').click();