@forgeax/interface 0.4.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -0
- package/dist/package/browser/ApplicationShell.js +1 -1
- package/dist/package/browser/appHostBootstrap.js +0 -2
- package/dist/package/browser/application.d.ts +0 -10
- package/dist/package/browser/application.js +0 -10
- package/dist/package/browser/components/CommandPalette/CommandPalette.js +1 -1
- package/dist/package/browser/core/app-shell/host.js +5 -2
- package/dist/package/browser/core/app-shell/types.d.ts +3 -1
- package/dist/package/browser/core/extensions/builtin-commands.js +1 -0
- package/dist/package/browser/core/extensions/trajectory.js +1 -1
- package/dist/package/browser/i18n/locales/en.json +0 -10
- package/dist/package/browser/i18n/locales/zh.json +0 -10
- package/dist/package/browser/lib/action-dom-discovery.js +1 -1
- package/dist/package/browser/lib/ai-intents.js +1 -1
- package/dist/package/browser/lib/builtin-actions.js +1 -1
- package/dist/package/browser/lib/global-shortcuts.d.ts +5 -74
- package/dist/package/browser/lib/global-shortcuts.js +29 -228
- package/dist/package/browser/lib/ui-action-highlight.js +1 -1
- package/dist/package/browser/lib/ui-bridge.js +1 -1
- package/dist/package/browser/lib/ui-trajectory.js +1 -1
- package/dist/package/browser/lib/vag-action-bridge.js +1 -1
- package/dist/package/node/ApplicationShell.js +1 -1
- package/dist/package/node/appHostBootstrap.js +0 -2
- package/dist/package/node/application.js +0 -10
- package/dist/package/node/components/CommandPalette/CommandPalette.js +1 -1
- package/dist/package/node/core/app-shell/host.js +5 -2
- package/dist/package/node/core/extensions/builtin-commands.js +1 -0
- package/dist/package/node/core/extensions/trajectory.js +1 -1
- package/dist/package/node/i18n/locales/en.json +0 -10
- package/dist/package/node/i18n/locales/zh.json +0 -10
- package/dist/package/node/lib/action-dom-discovery.js +1 -1
- package/dist/package/node/lib/ai-intents.js +1 -1
- package/dist/package/node/lib/builtin-actions.js +1 -1
- package/dist/package/node/lib/global-shortcuts.js +29 -228
- package/dist/package/node/lib/ui-action-highlight.js +1 -1
- package/dist/package/node/lib/ui-bridge.js +1 -1
- package/dist/package/node/lib/ui-trajectory.js +1 -1
- package/dist/package/node/lib/vag-action-bridge.js +1 -1
- package/package.json +2 -2
- package/dist/package/browser/core/extensions/editor-commands.d.ts +0 -2
- package/dist/package/browser/core/extensions/editor-commands.js +0 -182
- package/dist/package/browser/lib/action-registry.d.ts +0 -94
- package/dist/package/browser/lib/action-registry.js +0 -210
- package/dist/package/node/core/extensions/editor-commands.js +0 -182
- package/dist/package/node/lib/action-registry.js +0 -210
package/README.md
CHANGED
|
@@ -2,6 +2,57 @@
|
|
|
2
2
|
|
|
3
3
|
forgeax 前端工程(Studio 三栏 UI)。
|
|
4
4
|
|
|
5
|
+
## Application shortcut ownership (0.6.0)
|
|
6
|
+
|
|
7
|
+
> [!IMPORTANT]
|
|
8
|
+
> `configureInterfaceKeyboardRouter`, `KeyboardRouterDeps` and the private
|
|
9
|
+
> `editor-commands` extension have been removed. Products must install their
|
|
10
|
+
> Editor-owned keyboard extension through application bootstrap overrides.
|
|
11
|
+
> Interface consumes exact `@forgeax/app-shell@0.87.1`; no module-global Editor
|
|
12
|
+
> callback setter or second keyboard listener remains.
|
|
13
|
+
|
|
14
|
+
| Owner | Responsibility |
|
|
15
|
+
| :-- | :-- |
|
|
16
|
+
| App Shell | Per-host `shortcuts` registration, live snapshots and stale-callback fencing |
|
|
17
|
+
| Interface | One capture listener, contextual first refusal, shell bindings, typing/preview/surface guards and focused `text.selectAll` |
|
|
18
|
+
| Editor | Editor shortcuts, Play Escape, viewport callbacks and the twelve `editor.*` commands |
|
|
19
|
+
|
|
20
|
+
`useGlobalShortcuts(host.keybindings, host.shortcuts)` requires both host APIs.
|
|
21
|
+
Shortcut settings read `buildShortcuts(host.shortcuts)` so contributions added
|
|
22
|
+
or removed after boot are not hidden behind an earlier snapshot. A matched
|
|
23
|
+
shortcut returning `false` still terminates routing while yielding browser
|
|
24
|
+
default behavior. Shell bindings retain priority 10, Play-only Escape uses 20,
|
|
25
|
+
ordinary contributions use 0, and the palette fallback uses -20.
|
|
26
|
+
|
|
27
|
+
The normal/detached product shells, startup and global CSS remain Interface
|
|
28
|
+
entrypoints; this release does not complete their migration.
|
|
29
|
+
|
|
30
|
+
## Public action registry migration (0.5.0)
|
|
31
|
+
|
|
32
|
+
> [!IMPORTANT]
|
|
33
|
+
> Action registration and dispatch now belong to `@forgeax/app-shell/application`.
|
|
34
|
+
> Interface no longer exports these functions or their types through `application`
|
|
35
|
+
> or `lib/action-registry`. Consumers must use the same exact App Shell version as
|
|
36
|
+
> Interface so product discovery and external registration share one registry.
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import {
|
|
40
|
+
dispatchAction,
|
|
41
|
+
registerAction,
|
|
42
|
+
type UiActionDef,
|
|
43
|
+
} from '@forgeax/app-shell/application';
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
| App Shell owns | Interface retains |
|
|
47
|
+
| :-- | :-- |
|
|
48
|
+
| Registration, replacement-safe disposal and registry notifications | Product action definitions and capability declarations |
|
|
49
|
+
| Dispatch validation, source events and structured results | Handler behavior, permission decisions and visual feedback |
|
|
50
|
+
| Derived action/state snapshots and manifest metadata | DOM discovery, command-palette presentation and bridge wiring |
|
|
51
|
+
|
|
52
|
+
Application startup, normal/detached shells and global CSS remain Interface
|
|
53
|
+
entrypoints. This change removes the registry implementation, not those product
|
|
54
|
+
dependencies; it adds no compatibility facade or second action registry.
|
|
55
|
+
|
|
5
56
|
## 技术栈
|
|
6
57
|
|
|
7
58
|
- **Bun** runtime · **Vite 6** dev server · **React 19** · **TypeScript**
|
|
@@ -25,7 +25,7 @@ import { isTauri } from './lib/platform/runtime';
|
|
|
25
25
|
import './App.css';
|
|
26
26
|
export { ApplicationDetachedShell } from './ApplicationDetachedShell';
|
|
27
27
|
function KeyboardRouter({ runtime }) {
|
|
28
|
-
useGlobalShortcuts(runtime.host.keybindings);
|
|
28
|
+
useGlobalShortcuts(runtime.host.keybindings, runtime.host.shortcuts);
|
|
29
29
|
return null;
|
|
30
30
|
}
|
|
31
31
|
export function isApplicationOnboardingEnabled(onboarding) {
|
|
@@ -21,7 +21,6 @@ import { foundationStorageExtension } from './core/extensions/foundation-storage
|
|
|
21
21
|
import { builtinCommandsExtension } from './core/extensions/builtin-commands';
|
|
22
22
|
import { hostCommandsExtension } from './core/extensions/host-commands';
|
|
23
23
|
import { builtinMenusExtension } from './core/extensions/builtin-menus';
|
|
24
|
-
import { editorCommandsExtension } from './core/extensions/editor-commands';
|
|
25
24
|
import { panelsViewportExtension } from './core/extensions/panels-viewport';
|
|
26
25
|
import { panelsChatExtension } from './core/extensions/panels-chat';
|
|
27
26
|
import { chromeStatusBarExtension } from './core/extensions/chrome-statusbar';
|
|
@@ -108,7 +107,6 @@ export async function bootstrapAppHost(overrides = {}) {
|
|
|
108
107
|
builtinCommandsExtension,
|
|
109
108
|
hostCommandsExtension,
|
|
110
109
|
builtinMenusExtension,
|
|
111
|
-
editorCommandsExtension,
|
|
112
110
|
panelsViewportExtension,
|
|
113
111
|
panelsChatExtension,
|
|
114
112
|
chromeStatusBarExtension,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { AppHost as ApplicationHost } from '@forgeax/app-shell/application';
|
|
2
2
|
import { type AppHostBootstrapOverrides, type AppHostBootstrapResult } from './appHostBootstrap';
|
|
3
3
|
import { type Locale } from './i18n';
|
|
4
|
-
import { type KeyboardRouterDeps } from './lib/global-shortcuts';
|
|
5
4
|
export type InterfaceApplicationRuntime = AppHostBootstrapResult & {
|
|
6
5
|
readonly host: AppHostBootstrapResult['host'] & ApplicationHost;
|
|
7
6
|
};
|
|
@@ -16,12 +15,6 @@ export interface InterfaceApplicationStartupOptions {
|
|
|
16
15
|
* are observed. Product errors still propagate.
|
|
17
16
|
*/
|
|
18
17
|
export declare function installApplicationOverlayRedirect(overlayId: string, onRedirect: () => void): () => void;
|
|
19
|
-
/**
|
|
20
|
-
* Configures product-owned editor callbacks consumed by Interface's single
|
|
21
|
-
* keyboard router. Product assemblies use this public application boundary;
|
|
22
|
-
* the router implementation remains private to Interface.
|
|
23
|
-
*/
|
|
24
|
-
export declare function configureInterfaceKeyboardRouter(deps: KeyboardRouterDeps | null): void;
|
|
25
18
|
/**
|
|
26
19
|
* Starts the shared Interface application runtime without selecting a product
|
|
27
20
|
* entry or product extensions. IDE and compatibility callers supply their own
|
|
@@ -29,7 +22,4 @@ export declare function configureInterfaceKeyboardRouter(deps: KeyboardRouterDep
|
|
|
29
22
|
*/
|
|
30
23
|
export declare function startInterfaceApplication(overrides?: AppHostBootstrapOverrides, options?: InterfaceApplicationStartupOptions): Promise<InterfaceApplicationRuntime>;
|
|
31
24
|
export type { AppHostBootstrapOverrides } from './appHostBootstrap';
|
|
32
|
-
export type { KeyboardRouterDeps } from './lib/global-shortcuts';
|
|
33
25
|
export { configureStudioDomainClients, type StudioDomainClients, } from './store-parts/domain-clients';
|
|
34
|
-
export { dispatchAction, registerAction } from './lib/action-registry';
|
|
35
|
-
export type { JsonSchemaObject, UiActionDef, UiActionResult, UiCapability, } from './lib/action-registry';
|
|
@@ -2,7 +2,6 @@ import { bootstrapAppHost, } from './appHostBootstrap';
|
|
|
2
2
|
import { bootStageAppMounted } from './boot/driver';
|
|
3
3
|
import { changeLanguage, initI18n } from './i18n';
|
|
4
4
|
import { useShellStore } from './store';
|
|
5
|
-
import { registerKeyboardRouterDeps, } from './lib/global-shortcuts';
|
|
6
5
|
/**
|
|
7
6
|
* Lets a product replace one shell overlay with its own destination. Interface
|
|
8
7
|
* owns observation, clearing and synchronous reentry; the product owns routing.
|
|
@@ -24,14 +23,6 @@ export function installApplicationOverlayRedirect(overlayId, onRedirect) {
|
|
|
24
23
|
}
|
|
25
24
|
});
|
|
26
25
|
}
|
|
27
|
-
/**
|
|
28
|
-
* Configures product-owned editor callbacks consumed by Interface's single
|
|
29
|
-
* keyboard router. Product assemblies use this public application boundary;
|
|
30
|
-
* the router implementation remains private to Interface.
|
|
31
|
-
*/
|
|
32
|
-
export function configureInterfaceKeyboardRouter(deps) {
|
|
33
|
-
registerKeyboardRouterDeps(deps);
|
|
34
|
-
}
|
|
35
26
|
/**
|
|
36
27
|
* Starts the shared Interface application runtime without selecting a product
|
|
37
28
|
* entry or product extensions. IDE and compatibility callers supply their own
|
|
@@ -61,4 +52,3 @@ export async function startInterfaceApplication(overrides = {}, options = {}) {
|
|
|
61
52
|
// Product boot injects the existing domain authority without importing store
|
|
62
53
|
// internals. This is the same configuration function, not another client registry.
|
|
63
54
|
export { configureStudioDomainClients, } from './store-parts/domain-clients';
|
|
64
|
-
export { dispatchAction, registerAction } from './lib/action-registry';
|
|
@@ -12,7 +12,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
12
12
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
13
13
|
import { Command } from 'cmdk';
|
|
14
14
|
import { createRestartableTimeoutTaskLifecycle } from '@forgeax/app-shell/react';
|
|
15
|
-
import { dispatchAction, getAction, snapshotActions, } from '
|
|
15
|
+
import { dispatchAction, getAction, snapshotActions, } from '@forgeax/app-shell/application';
|
|
16
16
|
import { setCommandPaletteOpen, useCommandPaletteOpen } from '../../lib/command-palette-store';
|
|
17
17
|
import './CommandPalette.css';
|
|
18
18
|
/** 从 action 的 JSON Schema 派生顶层参数清单(与 registry 的 validateArgs 同口径)。 */
|
|
@@ -13,8 +13,9 @@ import { derivePanelRenderers } from './derive-panel-renderers';
|
|
|
13
13
|
import { DEFAULT_PANEL_RENDERERS } from '../../components/DockShell/panelRenderers';
|
|
14
14
|
import { installPageNavigation } from '../page-navigation';
|
|
15
15
|
import { createContextualKeybindings } from '../contextual-keybindings';
|
|
16
|
+
import { createApplicationShortcutRegistry } from '@forgeax/app-shell/application';
|
|
16
17
|
const BUILT_IN_CAPS = [
|
|
17
|
-
'commands', 'keybindings', 'bus', 'storage', 'panels', 'panelActions', 'panelControls', 'contextKeys', 'pages',
|
|
18
|
+
'commands', 'keybindings', 'shortcuts', 'bus', 'storage', 'panels', 'panelActions', 'panelControls', 'contextKeys', 'pages',
|
|
18
19
|
'activities', 'resourceEditors',
|
|
19
20
|
];
|
|
20
21
|
export function createAppHost(deps = {}) {
|
|
@@ -23,6 +24,7 @@ export function createAppHost(deps = {}) {
|
|
|
23
24
|
for (const c of BUILT_IN_CAPS)
|
|
24
25
|
caps.add(c);
|
|
25
26
|
const commands = createCommandsRegistry();
|
|
27
|
+
const shortcuts = createApplicationShortcutRegistry();
|
|
26
28
|
const keybindings = createContextualKeybindings(commands, {
|
|
27
29
|
onCommandError(error, commandId) {
|
|
28
30
|
log.error(`[app-shell] keybinding command "${commandId}" failed`, error);
|
|
@@ -62,7 +64,7 @@ export function createAppHost(deps = {}) {
|
|
|
62
64
|
const extensionFields = {};
|
|
63
65
|
let activeSetup = null;
|
|
64
66
|
const base = {
|
|
65
|
-
commands, keybindings, bus, storage, contextKeys,
|
|
67
|
+
commands, keybindings, shortcuts, bus, storage, contextKeys,
|
|
66
68
|
get panels() { return panelsSnapshot(); },
|
|
67
69
|
panelActions,
|
|
68
70
|
panelControls,
|
|
@@ -181,6 +183,7 @@ export function createAppHost(deps = {}) {
|
|
|
181
183
|
removePageNavigation();
|
|
182
184
|
await pageSession.dispose();
|
|
183
185
|
keybindings.dispose();
|
|
186
|
+
shortcuts.dispose();
|
|
184
187
|
bus.destroy();
|
|
185
188
|
},
|
|
186
189
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ApplicationShortcutRegistry } from '@forgeax/app-shell/application';
|
|
1
2
|
import type { ExtensionManifest, Cleanup } from '../extension-foundation';
|
|
2
3
|
import type { EventBus } from '../extension-foundation/bus';
|
|
3
4
|
import type { CommandsRegistry, CommandDescriptor } from '../extension-foundation/commands';
|
|
@@ -103,7 +104,7 @@ export interface AppBusEventMap extends Record<string, unknown> {
|
|
|
103
104
|
provider: string;
|
|
104
105
|
};
|
|
105
106
|
}
|
|
106
|
-
export type HostCapability = 'commands' | 'keybindings' | 'bus' | 'storage' | 'panels' | 'panelActions' | 'panelControls' | 'contextKeys' | 'pages' | 'activities' | 'resourceEditors' | 'session' | 'observability' | 'editor' | (string & {});
|
|
107
|
+
export type HostCapability = 'commands' | 'keybindings' | 'shortcuts' | 'bus' | 'storage' | 'panels' | 'panelActions' | 'panelControls' | 'contextKeys' | 'pages' | 'activities' | 'resourceEditors' | 'session' | 'observability' | 'editor' | (string & {});
|
|
107
108
|
export interface AppLogger {
|
|
108
109
|
debug(message: string, ...rest: unknown[]): void;
|
|
109
110
|
info(message: string, ...rest: unknown[]): void;
|
|
@@ -113,6 +114,7 @@ export interface AppLogger {
|
|
|
113
114
|
export interface AppHostBase {
|
|
114
115
|
readonly commands: CommandsRegistry;
|
|
115
116
|
readonly keybindings: ContextualKeybindingsApi;
|
|
117
|
+
readonly shortcuts: ApplicationShortcutRegistry;
|
|
116
118
|
readonly bus: EventBus<AppBusEventMap>;
|
|
117
119
|
readonly storage: StorageApi;
|
|
118
120
|
readonly contextKeys: ContextKeysApi;
|
|
@@ -38,6 +38,7 @@ export const builtinCommandsExtension = {
|
|
|
38
38
|
registerTextEditCommand('text.cut', '剪切输入框选区', 'cut');
|
|
39
39
|
registerTextEditCommand('text.copy', '复制输入框选区', 'copy');
|
|
40
40
|
registerTextEditCommand('text.paste', '粘贴到输入框', 'paste');
|
|
41
|
+
registerTextEditCommand('text.selectAll', 'Select all focused text', 'selectAll');
|
|
41
42
|
cleanups.push(registerCommand({
|
|
42
43
|
id: 'app.panel.open',
|
|
43
44
|
title: 'Open (or focus) a dock panel by id',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { registerAction, registerStateSlice } from '
|
|
1
|
+
import { registerAction, registerStateSlice } from '@forgeax/app-shell/application';
|
|
2
2
|
import { TRAJECTORY_MAX, clearTrajectory, readTrajectory, startTrajectoryRecording, } from '../../lib/ui-trajectory';
|
|
3
3
|
/** 随每次 ui_snapshot 内联出墙的尾部条数(压 token;更多靠 trajectory.read 拉)。 */
|
|
4
4
|
const SNAPSHOT_TAIL = 20;
|
|
@@ -1288,22 +1288,12 @@
|
|
|
1288
1288
|
"toggleDashboard": "Toggle Dashboard overview panel",
|
|
1289
1289
|
"toggleSettings": "Open / close Settings overlay",
|
|
1290
1290
|
"openChangelog": "Settings → About (changelog)",
|
|
1291
|
-
"hideSelected": "Hide selected entities (UE parity · editor-only, never affects the game)",
|
|
1292
|
-
"hideUnselected": "Hide unselected entities (isolate selection)",
|
|
1293
|
-
"showAllHidden": "Show all hidden entities",
|
|
1294
1291
|
"closeOverlay": "Close current overlay · browser fullscreen → game fullscreen → Settings → Dashboard in order",
|
|
1295
1292
|
"modePreview": "Switch to Preview mode",
|
|
1296
1293
|
"modePage": "Switch to Page mode",
|
|
1297
1294
|
"switchPageN": "Switch to extension {{n}} (Blender parity — indexed into extension list)",
|
|
1298
1295
|
"openExtensions": "Settings → Extensions (was the Bus mode tab)",
|
|
1299
1296
|
"focusComposer": "Focus the right ChatPanel composer",
|
|
1300
|
-
"duplicateSelection": "Duplicate selection",
|
|
1301
|
-
"toggleViewportGameView": "Toggle viewport Game View",
|
|
1302
|
-
"undo": "Undo",
|
|
1303
|
-
"redo": "Redo",
|
|
1304
|
-
"save": "Save",
|
|
1305
|
-
"viewportNavigation": "Viewport navigation and gizmo mode",
|
|
1306
|
-
"shieldGameInput": "Shield game input while editor-owned",
|
|
1307
1297
|
"toggleCommandPalette": "Toggle command palette"
|
|
1308
1298
|
},
|
|
1309
1299
|
"analytics": {
|
|
@@ -1288,22 +1288,12 @@
|
|
|
1288
1288
|
"toggleDashboard": "切换 Dashboard 总览面板",
|
|
1289
1289
|
"toggleSettings": "打开 / 关闭 Settings 浮层",
|
|
1290
1290
|
"openChangelog": "Settings → 关于(更新日志)",
|
|
1291
|
-
"hideSelected": "隐藏选中实体(UE 对标 · 编辑器临时隐藏,不影响游戏)",
|
|
1292
|
-
"hideUnselected": "隐藏未选中实体(孤立选择)",
|
|
1293
|
-
"showAllHidden": "显示所有隐藏实体",
|
|
1294
1291
|
"closeOverlay": "关闭当前浮层 · 浏览器全屏 → 游戏全屏 → Settings → Dashboard 依次撤回",
|
|
1295
1292
|
"modePreview": "切到 Preview 模式",
|
|
1296
1293
|
"modePage": "切到 Page 模式",
|
|
1297
1294
|
"switchPageN": "切到第 {{n}} 个 extension(Blender 风格 · 按列表索引)",
|
|
1298
1295
|
"openExtensions": "Settings → Extensions(原 Bus mode tab)",
|
|
1299
1296
|
"focusComposer": "聚焦右侧 ChatPanel 输入框",
|
|
1300
|
-
"duplicateSelection": "复制选中项",
|
|
1301
|
-
"toggleViewportGameView": "切换视口 Game View",
|
|
1302
|
-
"undo": "撤销",
|
|
1303
|
-
"redo": "重做",
|
|
1304
|
-
"save": "保存",
|
|
1305
|
-
"viewportNavigation": "视口导航与 Gizmo 模式",
|
|
1306
|
-
"shieldGameInput": "编辑器接管时屏蔽游戏输入",
|
|
1307
1297
|
"toggleCommandPalette": "切换命令面板"
|
|
1308
1298
|
},
|
|
1309
1299
|
"analytics": {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* data-fx-capability 权限分级(8 类之一;缺省 'other'。危险按钮**务必**标
|
|
13
13
|
* delete/credential,编排层会据此弹确认卡)
|
|
14
14
|
*/
|
|
15
|
-
import { registerAction } from '
|
|
15
|
+
import { registerAction } from '@forgeax/app-shell/application';
|
|
16
16
|
const VALID_CAPS = new Set([
|
|
17
17
|
'read', 'write', 'delete', 'exec', 'network', 'credential', 'delegate', 'other',
|
|
18
18
|
]);
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* surface 口径(方案 §5):纯视图操作 'ui';背后是 server REST 的标 'both'(headless
|
|
9
9
|
* 等价路径 P1 接线,声明先行,UI run() 已经就是调同一 HTTP API,server 是行为 SSOT)。
|
|
10
10
|
*/
|
|
11
|
-
import { registerAction, registerStateSlice } from '
|
|
11
|
+
import { registerAction, registerStateSlice } from '@forgeax/app-shell/application';
|
|
12
12
|
import { getSessionClient } from '../store-parts/session-client';
|
|
13
13
|
import { useShellStore, tabLabel } from '../store';
|
|
14
14
|
import { openExtensionPage, resolveRegisteredOverlayId } from '../core/page-navigation';
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* Ctrl+/ focus chat composer
|
|
11
11
|
* Ctrl+Shift+H open Settings → Changelog (was Ctrl+H before 2026-08-04 —
|
|
12
12
|
* UE-parity editor hide claimed Ctrl+H for "show all hidden")
|
|
13
|
-
* Esc
|
|
13
|
+
* Esc close current overlay (higher-priority owners may claim it)
|
|
14
14
|
* (Settings → Dashboard → Fullscreen)
|
|
15
15
|
*
|
|
16
16
|
* IME 安全:
|
|
@@ -21,75 +21,15 @@
|
|
|
21
21
|
*
|
|
22
22
|
* 注册:在 App 顶层调用 `useGlobalShortcuts()` 一次。
|
|
23
23
|
*/
|
|
24
|
+
import type { ApplicationShortcut, ApplicationShortcutRegistry } from '@forgeax/app-shell/application';
|
|
24
25
|
import type { ContextualKeybindingsApi } from '../core/contextual-keybindings';
|
|
25
|
-
export
|
|
26
|
-
/** 显示给用户的字符串,e.g. "Ctrl+Shift+F"。Mac 上 UI 会自动替换 Ctrl → ⌘/⌃。 */
|
|
27
|
-
combo: string;
|
|
28
|
-
/** 触发条件:keydown event → boolean。 */
|
|
29
|
-
match: (e: KeyboardEvent) => boolean;
|
|
30
|
-
/** 一行描述,显示在 Settings 表里。 */
|
|
31
|
-
label: string;
|
|
32
|
-
/** 分组(Layout / Mode / Overlay / Focus / general / edit)。 */
|
|
33
|
-
group: 'layout' | 'mode' | 'overlay' | 'focus' | 'general' | 'edit';
|
|
34
|
-
/** 触发动作。返回 true 表示 preventDefault。 */
|
|
35
|
-
run: (e?: KeyboardEvent) => boolean | void;
|
|
36
|
-
/** Esc 这种允许在 input 里触发(其他必须 target 不是 editable 才触发)。 */
|
|
37
|
-
allowInInput?: boolean;
|
|
38
|
-
}
|
|
26
|
+
export type ShortcutDef = ApplicationShortcut;
|
|
39
27
|
export declare function isTypingTarget(e: KeyboardEvent): boolean;
|
|
40
28
|
/** Preview canvases own their edit-domain keyboard input locally. */
|
|
41
29
|
export declare function isKeyboardOwnedSurface(e: KeyboardEvent): boolean;
|
|
42
30
|
export declare function shouldSkipGlobalShortcut(e: KeyboardEvent, shortcut: Pick<ShortcutDef, 'group'>): boolean;
|
|
43
31
|
export declare function isComposing(e: KeyboardEvent): boolean;
|
|
44
32
|
export declare function isEditorSurfaceActive(): boolean;
|
|
45
|
-
export interface RouterSelectedAsset {
|
|
46
|
-
guid: string;
|
|
47
|
-
kind: string;
|
|
48
|
-
name: string;
|
|
49
|
-
packPath: string;
|
|
50
|
-
payload: Record<string, unknown>;
|
|
51
|
-
}
|
|
52
|
-
export interface KeyboardRouterDeps {
|
|
53
|
-
/** Dispatch an editor op through the one gateway door. */
|
|
54
|
-
dispatch: (op: {
|
|
55
|
-
kind: string;
|
|
56
|
-
[k: string]: unknown;
|
|
57
|
-
}, origin?: string) => void;
|
|
58
|
-
/** Current entity-selection handles (for Ctrl+D / H routing). */
|
|
59
|
-
getEntitySelection: () => number[];
|
|
60
|
-
/** Current asset-selection list (for Ctrl+D routing). */
|
|
61
|
-
getAssetSelection: () => RouterSelectedAsset[];
|
|
62
|
-
/** Derive of "who was selected last" — retained for not-yet-migrated Ctrl+D. */
|
|
63
|
-
getLastSelectionDomain: () => 'entity' | 'asset' | 'folder' | null;
|
|
64
|
-
/** True under ▶ Play. */
|
|
65
|
-
isPlayMode: () => boolean;
|
|
66
|
-
/** Current viewport display axis (for G / Shift+G Game View toggle, AC-Cb4). */
|
|
67
|
-
getDisplay: () => 'scene' | 'game';
|
|
68
|
-
/** Current input owner. */
|
|
69
|
-
getInputTarget: () => 'editor' | 'game';
|
|
70
|
-
/** Legacy command-registry support; no longer bound to global Delete. */
|
|
71
|
-
deleteEntities: (ids: number[]) => void;
|
|
72
|
-
/** Entity: duplicate the given handles. */
|
|
73
|
-
duplicateEntities: (ids: number[]) => void;
|
|
74
|
-
/** Entity: hide the given handles (H — UE parity; one transaction, one undo). */
|
|
75
|
-
hideEntities: (ids: number[]) => void;
|
|
76
|
-
/** Entity: show every hidden entity (Ctrl+H — UE parity). */
|
|
77
|
-
showAllHidden: () => void;
|
|
78
|
-
/** Entity: hide everything not selected (Shift+H — isolate selection). */
|
|
79
|
-
hideUnselected: () => void;
|
|
80
|
-
/** Legacy command-registry support; no longer bound to global Mod+A. */
|
|
81
|
-
selectAllEntities: () => void;
|
|
82
|
-
/** Asset: duplicate the given asset (guid, packPath). */
|
|
83
|
-
duplicateAsset: (guid: string, packPath: string) => void;
|
|
84
|
-
/** Editor history actions, injected so the interface stays editor-agnostic. */
|
|
85
|
-
undo: () => void;
|
|
86
|
-
redo: () => void;
|
|
87
|
-
save: () => void;
|
|
88
|
-
/** Recreate the active Play/runtime surface after a terminal viewport failure. */
|
|
89
|
-
restartPreview?: () => void;
|
|
90
|
-
/** Viewport W/E/R/F handling, including fly-mode/input ownership policy. */
|
|
91
|
-
handleViewportKeyDown: (event: KeyboardEvent) => void;
|
|
92
|
-
}
|
|
93
33
|
/**
|
|
94
34
|
* Register a short-lived keydown owner for an interaction that is not a
|
|
95
35
|
* discoverable editor command (for example, Escape while a dock drag is
|
|
@@ -99,16 +39,7 @@ export interface KeyboardRouterDeps {
|
|
|
99
39
|
export type GlobalKeydownHandler = (event: KeyboardEvent) => boolean;
|
|
100
40
|
export declare function registerGlobalKeydownHandler(handler: GlobalKeydownHandler): () => void;
|
|
101
41
|
export declare function dispatchGlobalKeydownHandlers(event: KeyboardEvent): boolean;
|
|
102
|
-
|
|
103
|
-
* (forgeax-editor standalone/main.tsx) BEFORE the App mounts (useGlobalShortcuts
|
|
104
|
-
* reads this at effect time, which is after mount, so registration first is safe). */
|
|
105
|
-
export declare function registerKeyboardRouterDeps(deps: KeyboardRouterDeps | null): void;
|
|
106
|
-
/** Read the currently injected router deps. Returns null until the host has
|
|
107
|
-
* called registerKeyboardRouterDeps() at boot. Command-bus wrappers
|
|
108
|
-
* (editor-commands extension) resolve deps lazily via this getter so they
|
|
109
|
-
* stay editor-agnostic and boot-order-safe. */
|
|
110
|
-
export declare function getKeyboardRouterDeps(): KeyboardRouterDeps | null;
|
|
111
|
-
export declare function buildShortcuts(): ShortcutDef[];
|
|
42
|
+
export declare function buildShortcuts(contributions?: ApplicationShortcutRegistry): ShortcutDef[];
|
|
112
43
|
/**
|
|
113
44
|
* Mount once at App root. Returns nothing — purely an effect.
|
|
114
45
|
*
|
|
@@ -117,5 +48,5 @@ export declare function buildShortcuts(): ShortcutDef[];
|
|
|
117
48
|
* Ctrl+Shift+1/2/3 (which Chrome maps to tab switching only WITHOUT Shift,
|
|
118
49
|
* so we're safe, but we preventDefault anyway).
|
|
119
50
|
*/
|
|
120
|
-
export declare function useGlobalShortcuts(keybindings
|
|
51
|
+
export declare function useGlobalShortcuts(keybindings: ContextualKeybindingsApi, contributions: ApplicationShortcutRegistry): void;
|
|
121
52
|
export declare function prettyCombo(combo: string, platform?: 'mac' | 'windows'): string;
|