@dimina-kit/devtools 0.3.2-dev.20260611063505 → 0.4.0-dev.20260612025610

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.
Files changed (91) hide show
  1. package/README.md +56 -41
  2. package/dist/main/api.d.ts +4 -2
  3. package/dist/main/api.js +5 -1
  4. package/dist/main/app/app.d.ts +1 -5
  5. package/dist/main/app/app.js +25 -30
  6. package/dist/main/app/launch.d.ts +4 -4
  7. package/dist/main/app/launch.js +5 -17
  8. package/dist/main/index.bundle.js +535 -593
  9. package/dist/main/ipc/app.d.ts +1 -1
  10. package/dist/main/ipc/app.js +0 -7
  11. package/dist/main/ipc/index.d.ts +0 -2
  12. package/dist/main/ipc/index.js +0 -2
  13. package/dist/main/ipc/settings.d.ts +1 -1
  14. package/dist/main/ipc/settings.js +1 -13
  15. package/dist/main/ipc/simulator-module.d.ts +3 -3
  16. package/dist/main/ipc/simulator-module.js +3 -7
  17. package/dist/main/ipc/simulator.js +1 -12
  18. package/dist/main/menu/index.d.ts +2 -2
  19. package/dist/main/menu/index.js +4 -2
  20. package/dist/main/runtime/miniapp-runtime.d.ts +206 -28
  21. package/dist/main/runtime/miniapp-runtime.js +6 -11
  22. package/dist/main/services/layout/index.d.ts +0 -11
  23. package/dist/main/services/layout/index.js +0 -23
  24. package/dist/main/services/notifications/renderer-notifier.d.ts +0 -6
  25. package/dist/main/services/notifications/renderer-notifier.js +1 -10
  26. package/dist/main/services/service-host-pool/pool.d.ts +5 -4
  27. package/dist/main/services/views/host-toolbar-port-channel.d.ts +103 -0
  28. package/dist/main/services/views/host-toolbar-port-channel.js +248 -0
  29. package/dist/main/services/views/host-toolbar-session-runtime.d.ts +35 -0
  30. package/dist/main/services/views/host-toolbar-session-runtime.js +55 -0
  31. package/dist/main/services/views/view-manager.d.ts +80 -39
  32. package/dist/main/services/views/view-manager.js +153 -182
  33. package/dist/main/services/workbench-context.d.ts +13 -26
  34. package/dist/main/services/workbench-context.js +5 -14
  35. package/dist/main/services/workspace/workspace-service.d.ts +3 -7
  36. package/dist/main/services/workspace/workspace-service.js +34 -13
  37. package/dist/main/utils/paths.d.ts +11 -2
  38. package/dist/main/utils/paths.js +11 -2
  39. package/dist/main/windows/settings-window/index.d.ts +33 -0
  40. package/dist/main/windows/settings-window/index.js +59 -0
  41. package/dist/preload/index.d.ts +15 -0
  42. package/dist/preload/index.js +15 -0
  43. package/dist/preload/runtime/host-toolbar-port.d.ts +49 -0
  44. package/dist/preload/runtime/host-toolbar-port.js +151 -0
  45. package/dist/preload/runtime/host-toolbar-runtime.d.ts +41 -0
  46. package/dist/preload/runtime/host-toolbar-runtime.js +49 -0
  47. package/dist/preload/windows/{host-toolbar.cjs → host-toolbar-runtime.cjs} +103 -3
  48. package/dist/preload/windows/host-toolbar-runtime.cjs.map +7 -0
  49. package/dist/preload/windows/host-toolbar-runtime.d.ts +2 -0
  50. package/dist/preload/windows/host-toolbar-runtime.js +13 -0
  51. package/dist/preload/windows/simulator.cjs +0 -2
  52. package/dist/preload/windows/simulator.cjs.map +2 -2
  53. package/dist/preload/windows/simulator.js +0 -2
  54. package/dist/renderer/assets/constants-DI382mTP.js +2 -0
  55. package/dist/renderer/assets/index-DLzjz1wv.js +50 -0
  56. package/dist/renderer/assets/{input-CFHmbOgz.js → input-6fpCXV-n.js} +2 -2
  57. package/dist/renderer/assets/ipc-transport-Bs8Sf1B2.css +1 -0
  58. package/dist/renderer/assets/{ipc-transport-BkKKww3u.js → ipc-transport-D22e4dv7.js} +6 -6
  59. package/dist/renderer/assets/popover-CdGdKkkc.js +2 -0
  60. package/dist/renderer/assets/select-X0sbjwdP.js +2 -0
  61. package/dist/renderer/assets/{settings-Cl4IcWnG.js → settings-CS4jYaCw.js} +2 -2
  62. package/dist/renderer/assets/settings-api-CCWTAao_.js +2 -0
  63. package/dist/renderer/assets/workbenchSettings-Bpzaj3bm.js +8 -0
  64. package/dist/renderer/entries/main/index.html +7 -6
  65. package/dist/renderer/entries/popover/index.html +6 -6
  66. package/dist/renderer/entries/settings/index.html +5 -5
  67. package/dist/renderer/entries/workbench-settings/index.html +5 -5
  68. package/dist/shared/constants.d.ts +18 -0
  69. package/dist/shared/constants.js +18 -0
  70. package/dist/shared/ipc-channels.d.ts +10 -23
  71. package/dist/shared/ipc-channels.js +13 -34
  72. package/dist/shared/ipc-schemas.d.ts +0 -12
  73. package/dist/shared/ipc-schemas.js +0 -12
  74. package/dist/shared/types.d.ts +60 -76
  75. package/package.json +6 -6
  76. package/dist/main/ipc/panels.d.ts +0 -4
  77. package/dist/main/ipc/panels.js +0 -46
  78. package/dist/main/ipc/toolbar.d.ts +0 -4
  79. package/dist/main/ipc/toolbar.js +0 -21
  80. package/dist/main/services/toolbar/toolbar-store.d.ts +0 -23
  81. package/dist/main/services/toolbar/toolbar-store.js +0 -40
  82. package/dist/preload/windows/host-toolbar.cjs.map +0 -7
  83. package/dist/preload/windows/host-toolbar.d.ts +0 -2
  84. package/dist/preload/windows/host-toolbar.js +0 -12
  85. package/dist/renderer/assets/constants-CLAQX6VZ.js +0 -2
  86. package/dist/renderer/assets/index-CZQOpCvg.js +0 -50
  87. package/dist/renderer/assets/ipc-transport-Bv_BVu4T.css +0 -1
  88. package/dist/renderer/assets/popover-h1M7n3tt.js +0 -2
  89. package/dist/renderer/assets/select-kj0n1oYf.js +0 -2
  90. package/dist/renderer/assets/settings-api-CCwo2eOi.js +0 -2
  91. package/dist/renderer/assets/workbenchSettings-BzlpQnve.js +0 -8
@@ -1,4 +1,4 @@
1
1
  import type { WorkbenchContext } from '../services/workbench-context.js';
2
2
  import type { Disposable } from '@dimina-kit/electron-deck/main';
3
- export declare function registerAppIpc(ctx: Pick<WorkbenchContext, 'preloadPath' | 'brandingProvider' | 'appName' | 'headerHeight' | 'senderPolicy'>): Disposable;
3
+ export declare function registerAppIpc(ctx: Pick<WorkbenchContext, 'brandingProvider' | 'appName' | 'senderPolicy'>): Disposable;
4
4
  //# sourceMappingURL=app.d.ts.map
@@ -1,18 +1,11 @@
1
- import fs from 'fs';
2
1
  import { AppChannel } from '../../shared/ipc-channels.js';
3
2
  import { IpcRegistry } from '../utils/ipc-registry.js';
4
3
  export function registerAppIpc(ctx) {
5
4
  return new IpcRegistry(ctx.senderPolicy)
6
- .handle(AppChannel.GetPreloadPath, () => {
7
- return `file://${fs.realpathSync(ctx.preloadPath)}`;
8
- })
9
5
  .handle(AppChannel.GetBranding, async () => {
10
6
  if (ctx.brandingProvider)
11
7
  return ctx.brandingProvider();
12
8
  return { appName: ctx.appName };
13
- })
14
- .handle(AppChannel.GetHeaderHeight, () => {
15
- return ctx.headerHeight;
16
9
  });
17
10
  }
18
11
  //# sourceMappingURL=app.js.map
@@ -1,10 +1,8 @@
1
1
  export { registerAppIpc } from './app.js';
2
2
  export { registerSimulatorIpc } from './simulator.js';
3
- export { registerPanelsIpc } from './panels.js';
4
3
  export { registerPopoverIpc, popoverModule } from './popover.js';
5
4
  export { registerProjectsIpc, projectsModule } from './projects.js';
6
5
  export { registerSessionIpc, sessionModule } from './session.js';
7
6
  export { registerSettingsIpc, settingsModule } from './settings.js';
8
- export { registerToolbarIpc } from './toolbar.js';
9
7
  export { simulatorModule } from './simulator-module.js';
10
8
  //# sourceMappingURL=index.d.ts.map
@@ -1,10 +1,8 @@
1
1
  export { registerAppIpc } from './app.js';
2
2
  export { registerSimulatorIpc } from './simulator.js';
3
- export { registerPanelsIpc } from './panels.js';
4
3
  export { registerPopoverIpc, popoverModule } from './popover.js';
5
4
  export { registerProjectsIpc, projectsModule } from './projects.js';
6
5
  export { registerSessionIpc, sessionModule } from './session.js';
7
6
  export { registerSettingsIpc, settingsModule } from './settings.js';
8
- export { registerToolbarIpc } from './toolbar.js';
9
7
  export { simulatorModule } from './simulator-module.js';
10
8
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,6 @@
1
1
  import type { WorkbenchContext } from '../services/workbench-context.js';
2
2
  import type { Disposable } from '@dimina-kit/electron-deck/main';
3
3
  import type { WorkbenchModule } from '../services/module.js';
4
- export declare function registerSettingsIpc(ctx: Pick<WorkbenchContext, 'views' | 'notify' | 'workspace' | 'rendererDir' | 'senderPolicy' | 'windows'>): Disposable;
4
+ export declare function registerSettingsIpc(ctx: Pick<WorkbenchContext, 'views' | 'notify' | 'workspace' | 'rendererDir' | 'senderPolicy'>): Disposable;
5
5
  export declare const settingsModule: WorkbenchModule;
6
6
  //# sourceMappingURL=settings.d.ts.map
@@ -1,10 +1,9 @@
1
1
  import { app } from 'electron';
2
- import { openSettingsWindow } from '../app/launch.js';
3
2
  import { loadWorkbenchSettings, saveWorkbenchSettings, applyTheme, } from '../services/settings/index.js';
4
3
  import { WorkbenchSettingsChannel, SettingsChannel } from '../../shared/ipc-channels.js';
5
4
  import { DEFAULT_CDP_PORT } from '../../shared/constants.js';
6
5
  import { getMcpStatus } from '../services/mcp/status.js';
7
- import { SettingsConfigChangedSchema, SettingsProjectSettingsChangedSchema, SettingsSetVisibleSchema, WorkbenchSettingsSaveSchema, WorkbenchSettingsSetThemeSchema, WorkbenchSettingsSetVisibleSchema, } from '../../shared/ipc-schemas.js';
6
+ import { SettingsConfigChangedSchema, SettingsProjectSettingsChangedSchema, SettingsSetVisibleSchema, WorkbenchSettingsSaveSchema, WorkbenchSettingsSetThemeSchema, } from '../../shared/ipc-schemas.js';
8
7
  import { validate } from '../utils/ipc-schema.js';
9
8
  import { IpcRegistry } from '../utils/ipc-registry.js';
10
9
  export function registerSettingsIpc(ctx) {
@@ -44,15 +43,6 @@ export function registerSettingsIpc(ctx) {
44
43
  activePort: runtime.port,
45
44
  error: runtime.error,
46
45
  };
47
- })
48
- .handle(WorkbenchSettingsChannel.SetVisible, async (_, ...args) => {
49
- const [visible] = validate(WorkbenchSettingsChannel.SetVisible, WorkbenchSettingsSetVisibleSchema, args);
50
- if (visible) {
51
- await openSettingsWindow(ctx);
52
- }
53
- else {
54
- ctx.windows.closeSettingsWindow();
55
- }
56
46
  })
57
47
  .handle(SettingsChannel.SetVisible, async (_, ...args) => {
58
48
  const [visible] = validate(SettingsChannel.SetVisible, SettingsSetVisibleSchema, args);
@@ -67,7 +57,6 @@ export function registerSettingsIpc(ctx) {
67
57
  }
68
58
  else {
69
59
  ctx.views.hideSettings();
70
- ctx.notify.settingsClosed();
71
60
  }
72
61
  })
73
62
  .on(SettingsChannel.ConfigChanged, async (_, ...args) => {
@@ -76,7 +65,6 @@ export function registerSettingsIpc(ctx) {
76
65
  if (projectPath) {
77
66
  await ctx.workspace.saveCompileConfig(projectPath, config);
78
67
  }
79
- ctx.notify.settingsChanged(config);
80
68
  })
81
69
  .on(SettingsChannel.ProjectSettingsChanged, (_, ...args) => {
82
70
  const [patch] = validate(SettingsChannel.ProjectSettingsChanged, SettingsProjectSettingsChangedSchema, args);
@@ -1,8 +1,8 @@
1
1
  import type { WorkbenchModule } from '../services/module.js';
2
2
  /**
3
- * The 'simulator' built-in module fans out into three IPC registrars
4
- * (core simulator, panels, toolbar). Bundle them under a single module
5
- * so app.ts only sees one entry per BuiltinModuleId.
3
+ * The 'simulator' built-in module fans out into the simulator + views IPC
4
+ * registrars. Bundle them under a single module so app.ts only sees one
5
+ * entry per BuiltinModuleId.
6
6
  *
7
7
  * Bridge router (native-host PAGE_OPEN / NAV_ACTION / TAB_ACTION etc.) hooks
8
8
  * up unconditionally — the `__diminaNativeHost.enabled` flag in the simulator
@@ -1,13 +1,11 @@
1
1
  import { DisposableRegistry } from '@dimina-kit/electron-deck/main';
2
2
  import { registerSimulatorIpc } from './simulator.js';
3
- import { registerPanelsIpc } from './panels.js';
4
- import { registerToolbarIpc } from './toolbar.js';
5
3
  import { installBridgeRouter } from './bridge-router.js';
6
4
  import { registerViewsIpc } from './views.js';
7
5
  /**
8
- * The 'simulator' built-in module fans out into three IPC registrars
9
- * (core simulator, panels, toolbar). Bundle them under a single module
10
- * so app.ts only sees one entry per BuiltinModuleId.
6
+ * The 'simulator' built-in module fans out into the simulator + views IPC
7
+ * registrars. Bundle them under a single module so app.ts only sees one
8
+ * entry per BuiltinModuleId.
11
9
  *
12
10
  * Bridge router (native-host PAGE_OPEN / NAV_ACTION / TAB_ACTION etc.) hooks
13
11
  * up unconditionally — the `__diminaNativeHost.enabled` flag in the simulator
@@ -19,8 +17,6 @@ export const simulatorModule = {
19
17
  setup: (ctx) => {
20
18
  const reg = new DisposableRegistry();
21
19
  reg.add(registerSimulatorIpc(ctx));
22
- reg.add(registerPanelsIpc(ctx));
23
- reg.add(registerToolbarIpc(ctx));
24
20
  reg.add(registerViewsIpc(ctx));
25
21
  installBridgeRouter(ctx);
26
22
  return reg;
@@ -1,5 +1,5 @@
1
1
  import { ServiceHostChannel, SimulatorChannel, SimulatorCustomApiChannel } from '../../shared/ipc-channels.js';
2
- import { SimulatorAttachNativeSchema, SimulatorCustomApiInvokeSchema, SimulatorResizeSchema, SimulatorSetDeviceInfoSchema, SimulatorSetNativeBoundsSchema, SimulatorSetVisibleSchema, } from '../../shared/ipc-schemas.js';
2
+ import { SimulatorAttachNativeSchema, SimulatorCustomApiInvokeSchema, SimulatorSetDeviceInfoSchema, SimulatorSetNativeBoundsSchema, } from '../../shared/ipc-schemas.js';
3
3
  import { deviceInfoToHostEnv } from '../../shared/bridge-channels.js';
4
4
  import { validate } from '../utils/ipc-schema.js';
5
5
  import { IpcRegistry } from '../utils/ipc-registry.js';
@@ -11,10 +11,6 @@ export function registerSimulatorIpc(ctx) {
11
11
  })
12
12
  .handle(SimulatorChannel.Detach, () => {
13
13
  ctx.views.detachSimulator();
14
- })
15
- .handle(SimulatorChannel.Resize, (_, ...args) => {
16
- const [simWidth] = validate(SimulatorChannel.Resize, SimulatorResizeSchema, args);
17
- ctx.views.resize(simWidth);
18
14
  })
19
15
  .handle(SimulatorChannel.SetNativeBounds, (_, ...args) => {
20
16
  const [p] = validate(SimulatorChannel.SetNativeBounds, SimulatorSetNativeBoundsSchema, args);
@@ -38,13 +34,6 @@ export function registerSimulatorIpc(ctx) {
38
34
  if (serviceWc && !serviceWc.isDestroyed()) {
39
35
  serviceWc.send(ServiceHostChannel.HostEnvUpdate, deviceInfoToHostEnv(device));
40
36
  }
41
- })
42
- .handle(SimulatorChannel.SetVisible, (_, ...args) => {
43
- const [visible, simWidth] = validate(SimulatorChannel.SetVisible, SimulatorSetVisibleSchema, args);
44
- ctx.views.setVisible(visible, simWidth);
45
- })
46
- .handle(SimulatorCustomApiChannel.List, () => {
47
- return ctx.simulatorApis.list();
48
37
  })
49
38
  .handle(SimulatorCustomApiChannel.Invoke, (_, ...args) => {
50
39
  const [name, params] = validate(SimulatorCustomApiChannel.Invoke, SimulatorCustomApiInvokeSchema, args);
@@ -1,3 +1,3 @@
1
- import type { WorkbenchContext } from '../services/workbench-context.js';
2
- export declare function installAppMenu(ctx: WorkbenchContext): void;
1
+ import type { MenuContext } from '../../shared/types.js';
2
+ export declare function installAppMenu(ctx: MenuContext): void;
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1,5 +1,7 @@
1
1
  import { Menu } from 'electron';
2
- import { openSettingsWindow } from '../app/launch.js';
2
+ // The built-in menu consumes the narrow MenuContext, the same surface a host
3
+ // menuBuilder receives — proof that the hand-written contract covers the
4
+ // real internal consumption (settings entry + navigate-back).
3
5
  export function installAppMenu(ctx) {
4
6
  const template = [
5
7
  {
@@ -8,7 +10,7 @@ export function installAppMenu(ctx) {
8
10
  {
9
11
  label: '开发工具设置',
10
12
  click: () => {
11
- void openSettingsWindow(ctx).catch(() => { });
13
+ void ctx.openSettings().catch(() => { });
12
14
  },
13
15
  },
14
16
  { type: 'separator' },
@@ -1,39 +1,217 @@
1
1
  /**
2
2
  * MiniappRuntime — the stable, host-facing contract surface (foundation.md §3
3
- * "MiniappRuntime 契约" layer, P4).
3
+ * "MiniappRuntime 契约" layer).
4
4
  *
5
- * `WorkbenchContext` is the rich internal main-process state: runtime kernel +
6
- * host config + trust/infra plumbing, all mixed. Downstream hosts (qdmp, a
7
- * re-skin of devtools that depends ONLY on devtools) don't consume that whole
8
- * grab-bag they drive the miniapp KERNEL: the view lifecycle (including the
9
- * host-controllable toolbar at `views.hostToolbar`), the cross-wc bridge, the
10
- * workspace, the custom-API registry, async storage, the appdata tap, the
11
- * connection layer, and the main→renderer notifier.
5
+ * HAND-WRITTEN, not derived from `WorkbenchContext`. A `Pick`-style projection
6
+ * would drag every nested internal service type (ViewManager,
7
+ * BridgeRouterHandle, SimulatorApiRegistry, Electron WebContents…) onto the
8
+ * public semver face, so any internal refactor of those services becomes an
9
+ * unreviewed breaking change for downstream hosts (qdmp). Instead this module
10
+ * names ONLY the audited downstream consumption surface, with structural DTOs
11
+ * and zero Electron types non-Electron consumers can compile against it.
12
12
  *
13
- * This module NAMES that kernel as an explicit, documented contract so the
14
- * surface a host depends on is compiler-enforced and versionable, instead of
15
- * "whatever fields of WorkbenchContext you happen to reach for". Config inputs
16
- * (appName / panels / apiNamespaces / branding / project templates) are the
17
- * host's INPUT, not part of the runtime it consumes; trust/infra
18
- * (senderPolicy / trustedWindowSenderIds / registry / toolbar action-table)
19
- * stay internal.
20
- *
21
- * Derived via `Pick<WorkbenchContext, …>` so the field TYPES never drift from
22
- * the real implementation — `MiniappRuntime` is a view onto `WorkbenchContext`,
23
- * and the conformance assertion below fails to compile the moment the context
24
- * stops satisfying the contract.
13
+ * Contract rules:
14
+ * - Members are FUNCTION-VALUED PROPERTIES (`m: (x) => r`), never method
15
+ * syntax: under strictFunctionTypes method signatures compare bivariantly,
16
+ * which would let a wrongly-narrowed implementation or host override slip
17
+ * past the drift sentinel.
18
+ * - `workspace.openProject` stays writable (no `readonly`): qdmp gates
19
+ * project permissions by reassigning it (documented monkey-patch contract).
25
20
  *
26
- * The host-controllable toolbar WebContentsView hangs off `views.hostToolbar`
27
- * (a ViewManager concern), so it's reachable through the contract WITHOUT a 9th
28
- * top-level member `runtime.views.hostToolbar.loadURL(...)`.
21
+ * `asMiniappRuntime(ctx)` is an identity return the contract is a typed
22
+ * VIEW onto the live context, not a snapshot/projection. That is what makes
23
+ * the monkey-patch contract work (a copied projection would receive the patch
24
+ * on a dead object), and its `return ctx` doubles as the assignment-compat
25
+ * sentinel: if an internal service drifts away from the contract, compilation
26
+ * breaks HERE, in this package's CI — not in a downstream host's upgrade.
29
27
  */
30
28
  import type { WorkbenchContext } from '../services/workbench-context.js';
31
- /** The stable miniapp-kernel surface a downstream host (qdmp) consumes. */
32
- export type MiniappRuntime = Pick<WorkbenchContext, 'views' | 'bridge' | 'workspace' | 'simulatorApis' | 'storageApi' | 'appData' | 'connections' | 'notify'>;
29
+ /** Compile-status payload broadcast to hosts via `notify.projectStatus`. */
30
+ export interface MiniappProjectStatusPayload {
31
+ status: string;
32
+ message: string;
33
+ /** True when the status update is emitted by the file-watcher rebuild loop. */
34
+ hotReload?: boolean;
35
+ }
36
+ /**
37
+ * Structured shape of `getSession().appInfo` — the doc-promised
38
+ * (`host-migration.md` "appInfo 已结构化") DTO, named so hosts can type what
39
+ * they receive without deep imports or casts.
40
+ *
41
+ * `appId` is REQUIRED: the renderer derives its IPC scoping from it and the
42
+ * default devkit adapter always supplies one (fallback included). A custom
43
+ * adapter that returns a session without a string `appId` is rejected at the
44
+ * `openProject` boundary (see workspace-service.ts) — it never becomes the
45
+ * active session. The decorative rest stays optional: `name`/`path` come from
46
+ * the devkit adapter, `appName` from the devtools-side mirror; minimal custom
47
+ * adapters may omit all three.
48
+ */
49
+ export interface MiniappSessionAppInfo {
50
+ appId: string;
51
+ name?: string;
52
+ path?: string;
53
+ appName?: string;
54
+ }
55
+ /**
56
+ * The page-side bridge the framework injects into the host-toolbar WCV as
57
+ * `window.diminaHostToolbar` (see src/preload/runtime/host-toolbar-port.ts).
58
+ * Declared here (the electron-free contract module) so TypeScript toolbar
59
+ * pages can type the bridge without hand-rolling — and without importing
60
+ * anything Electron-flavored.
61
+ *
62
+ * Shape mirrors the injected bridge EXACTLY:
63
+ * - `send` returns void (pre-handshake sends are queued, bounded at 128);
64
+ * - `onMessage` returns a BARE un-subscribe function — unlike the main-side
65
+ * control's `{ dispose }` — because that is what the preload exposes.
66
+ * Both throw a `TypeError` synchronously when `channel` is not a non-empty
67
+ * string (parity with the main side's `onMessage` guard).
68
+ */
69
+ export interface DiminaHostToolbarPageBridge {
70
+ send: (channel: string, payload: unknown) => void;
71
+ onMessage: (channel: string, handler: (payload: unknown) => void) => () => void;
72
+ }
73
+ declare global {
74
+ interface Window {
75
+ /**
76
+ * Present ONLY inside the host-toolbar WebContentsView's main frame
77
+ * (guarded injection — see host-toolbar-runtime.ts); optional everywhere
78
+ * else, so page code must runtime-guard before use.
79
+ */
80
+ diminaHostToolbar?: DiminaHostToolbarPageBridge;
81
+ }
82
+ }
83
+ /**
84
+ * Host-facing control surface for the toolbar WebContentsView — the exact
85
+ * post-R2 message-channel surface (`send`/`onMessage`), with no `webContents`
86
+ * escape hatch (that would put Electron types on the contract).
87
+ */
88
+ export interface MiniappHostToolbar {
89
+ /**
90
+ * The host's own `webPreferences.preload` for the toolbar view (purely
91
+ * additive — never replaces the framework's session-resident height
92
+ * advertiser). Must be set before the view is (re)created; `null` (default)
93
+ * means "no host preload".
94
+ */
95
+ setPreloadPath: (path: string | null) => void;
96
+ /** Load a local file into the toolbar view (lazy-creates the view). */
97
+ loadFile: (path: string) => Promise<void>;
98
+ /** Load a URL into the toolbar view (lazy-creates the view). */
99
+ loadURL: (url: string) => Promise<void>;
100
+ /**
101
+ * Post `{ channel, payload }` to the toolbar page. Gated and non-queueing:
102
+ * returns false (delivering nothing, creating no view) while there is no
103
+ * live toolbar webContents or the current load's MessagePort handshake
104
+ * hasn't completed; true once the envelope went out.
105
+ */
106
+ send: (channel: string, payload: unknown) => boolean;
107
+ /**
108
+ * Register a host-side handler for messages the toolbar page sends via
109
+ * `window.diminaHostToolbar.send(channel, payload)`. May be called before
110
+ * the view exists; survives page reloads. `dispose()` detaches (idempotent).
111
+ */
112
+ onMessage: (channel: string, handler: (payload: unknown) => void) => {
113
+ dispose: () => void;
114
+ };
115
+ /**
116
+ * Observe handshake readiness. Fires the handler once per load generation,
117
+ * exactly when the toolbar page's MessagePort handshake completes (i.e.
118
+ * when `send` flips to true). Registering while the channel is already
119
+ * ready fires once asynchronously on a microtask (missed-signal guard);
120
+ * a reload / re-handshake fires registered handlers again. `dispose()`
121
+ * detaches (idempotent).
122
+ */
123
+ onReady: (handler: () => void) => {
124
+ dispose: () => void;
125
+ };
126
+ /**
127
+ * Pin (`{ fixed }`) or unpin (`'auto'`) the toolbar strip height. `'auto'`
128
+ * (default) lets the in-page height advertiser drive the placeholder.
129
+ * `{ fixed }` values must be finite and non-negative — anything else throws
130
+ * a `TypeError` synchronously and leaves the standing mode untouched.
131
+ */
132
+ setHeightMode: (mode: 'auto' | {
133
+ fixed: number;
134
+ }) => void;
135
+ }
136
+ /**
137
+ * The audited workspace surface: project list membership, session lifecycle,
138
+ * and minimal session state. Thumbnails / per-project settings / providers
139
+ * stay internal.
140
+ */
141
+ export interface MiniappWorkspace {
142
+ /** True while a project session is open. */
143
+ hasActiveSession: () => boolean;
144
+ /** Absolute path of the open project, or '' when none. */
145
+ getProjectPath: () => string;
146
+ /**
147
+ * Open (compile + start) a project session. WRITABLE BY CONTRACT: hosts may
148
+ * reassign this member to wrap it (e.g. a permission gate) — every internal
149
+ * caller routes through the live property, so the wrapper always intercepts.
150
+ */
151
+ openProject: (projectPath: string) => Promise<{
152
+ success: boolean;
153
+ error?: string;
154
+ }>;
155
+ /** Tear down the active session (no-op when none). */
156
+ closeProject: () => Promise<void>;
157
+ /** True when the directory is already in the project list. */
158
+ hasProject: (dirPath: string) => Promise<boolean>;
159
+ /** Add a directory to the project list. */
160
+ addProject: (dirPath: string) => Promise<unknown>;
161
+ /**
162
+ * Minimal live-session DTO, or null when no session. Deliberately excludes
163
+ * the session's own `close` — hosts end sessions via `closeProject`, never
164
+ * behind the workspace's back. `appInfo` is structured (see
165
+ * {@link MiniappSessionAppInfo}) — no casting required.
166
+ */
167
+ getSession: () => {
168
+ appInfo: MiniappSessionAppInfo;
169
+ } | null;
170
+ }
171
+ /**
172
+ * The stable miniapp-kernel surface a downstream host (qdmp) consumes.
173
+ * Compiler-enforced and versionable: widening it back toward internal
174
+ * plumbing is a deliberate semver decision, not an accident of projection.
175
+ */
176
+ export interface MiniappRuntime {
177
+ /** View layer — only the host-owned toolbar control is public. */
178
+ views: {
179
+ readonly hostToolbar: MiniappHostToolbar;
180
+ };
181
+ /** Project + session workspace (see {@link MiniappWorkspace}). */
182
+ workspace: MiniappWorkspace;
183
+ /** Main → renderer notifier — only the compile-status broadcast is public. */
184
+ notify: {
185
+ projectStatus: (payload: MiniappProjectStatusPayload) => void;
186
+ };
187
+ /**
188
+ * Lifecycle sink: hosts register their own teardown via `registry.add`.
189
+ * Accepts BOTH disposal idioms — a `{ dispose }` object (what
190
+ * `hostToolbar.onMessage`/`onReady` return) or a bare `() => void` —
191
+ * matching the live registry, so `registry.add(sub)` works without the
192
+ * `registry.add(() => sub.dispose())` wrapper.
193
+ */
194
+ registry: {
195
+ add: (d: {
196
+ dispose: () => void;
197
+ } | (() => void)) => void;
198
+ };
199
+ /**
200
+ * Open (or re-focus) the standalone workbench-settings window. Replaces the
201
+ * retired `windows` opaque pass-through (whose only documented purpose —
202
+ * `openSettingsWindow(ctx)` — could never typecheck from the contract) and
203
+ * the `rendererDir` member that existed solely to feed it; hosts needing
204
+ * the renderer dist path use the `/paths` export instead.
205
+ */
206
+ openSettings: () => Promise<void>;
207
+ }
33
208
  /**
34
- * Project a full `WorkbenchContext` down to its `MiniappRuntime` view. Hosts
35
- * call this to get a value typed to exactly the contract no wider access to
36
- * the context's internals leaks through.
209
+ * View a full `WorkbenchContext` as its `MiniappRuntime` contract. Identity
210
+ * return: the result IS the live context, typed down to the contract, so host
211
+ * monkey-patches (e.g. `runtime.workspace.openProject = gated`) land on the
212
+ * real object. The `return ctx` is also the compile-time drift sentinel — if
213
+ * `WorkbenchContext` ever stops structurally satisfying the contract, THIS
214
+ * stops compiling.
37
215
  */
38
216
  export declare function asMiniappRuntime(ctx: WorkbenchContext): MiniappRuntime;
39
217
  //# sourceMappingURL=miniapp-runtime.d.ts.map
@@ -1,17 +1,12 @@
1
1
  /**
2
- * Project a full `WorkbenchContext` down to its `MiniappRuntime` view. Hosts
3
- * call this to get a value typed to exactly the contract no wider access to
4
- * the context's internals leaks through.
2
+ * View a full `WorkbenchContext` as its `MiniappRuntime` contract. Identity
3
+ * return: the result IS the live context, typed down to the contract, so host
4
+ * monkey-patches (e.g. `runtime.workspace.openProject = gated`) land on the
5
+ * real object. The `return ctx` is also the compile-time drift sentinel — if
6
+ * `WorkbenchContext` ever stops structurally satisfying the contract, THIS
7
+ * stops compiling.
5
8
  */
6
9
  export function asMiniappRuntime(ctx) {
7
10
  return ctx;
8
11
  }
9
- /**
10
- * Compile-time conformance guard: if `WorkbenchContext` ever stops structurally
11
- * satisfying `MiniappRuntime` (a kernel field renamed / its type narrowed),
12
- * THIS line fails `tsc`, catching the contract break at build time. The runtime
13
- * value is unused.
14
- */
15
- const _conformance = (ctx) => ctx;
16
- void _conformance;
17
12
  //# sourceMappingURL=miniapp-runtime.js.map
@@ -1,20 +1,9 @@
1
- /** Layout constants (px) */
2
- export declare const SPLITTER_W = 4;
3
- /**
4
- * X coordinate where the legacy right-side overlay starts.
5
- */
6
- export declare function getRightX(simWidth: number): number;
7
1
  export interface Bounds {
8
2
  x: number;
9
3
  y: number;
10
4
  width: number;
11
5
  height: number;
12
6
  }
13
- export declare function computeRightPanelBounds(contentWidth: number, contentHeight: number, simWidth: number, headerHeight: number): Bounds;
14
- /**
15
- * Compute bounds for DevTools view (same as right panel, overlays it).
16
- */
17
- export declare function computeSimulatorBounds(contentWidth: number, contentHeight: number, simWidth: number, headerHeight: number): Bounds;
18
7
  /**
19
8
  * NATIVE-HOST ONLY. Translate the renderer-measured simulator panel REGION rect
20
9
  * (CSS px from the main window content top-left — the flex:1 placeholder slot)
@@ -1,26 +1,3 @@
1
- /** Layout constants (px) */
2
- export const SPLITTER_W = 4;
3
- /**
4
- * X coordinate where the legacy right-side overlay starts.
5
- */
6
- export function getRightX(simWidth) {
7
- return simWidth + SPLITTER_W;
8
- }
9
- export function computeRightPanelBounds(contentWidth, contentHeight, simWidth, headerHeight) {
10
- const x = getRightX(simWidth);
11
- return {
12
- x,
13
- y: headerHeight,
14
- width: Math.max(1, contentWidth - x),
15
- height: Math.max(1, contentHeight - headerHeight),
16
- };
17
- }
18
- /**
19
- * Compute bounds for DevTools view (same as right panel, overlays it).
20
- */
21
- export function computeSimulatorBounds(contentWidth, contentHeight, simWidth, headerHeight) {
22
- return computeRightPanelBounds(contentWidth, contentHeight, simWidth, headerHeight);
23
- }
24
1
  /**
25
2
  * NATIVE-HOST ONLY. Translate the renderer-measured simulator panel REGION rect
26
3
  * (CSS px from the main window content top-left — the flex:1 placeholder slot)
@@ -45,16 +45,10 @@ export interface RendererNotifier {
45
45
  projectStatus(payload: ProjectStatusPayload): void;
46
46
  /** Ask the main renderer to navigate back to its landing screen. */
47
47
  windowNavigateBack(): void;
48
- /** Tell the main renderer the embedded settings overlay has been closed. */
49
- settingsClosed(): void;
50
- /** Broadcast an updated compile config to the main renderer. */
51
- settingsChanged(config: CompileConfig): void;
52
48
  /** Tell the main renderer the compile popover has been closed. */
53
49
  popoverClosed(): void;
54
50
  /** Ask the main renderer to relaunch the simulator with a new config. */
55
51
  popoverRelaunch(config: CompileConfig): void;
56
- /** Tell the main renderer the toolbar actions list has changed. */
57
- toolbarActionsChanged(): void;
58
52
  /**
59
53
  * Push the reserved host-toolbar height to the main renderer so its toolbar
60
54
  * placeholder div resizes (closes the host-toolbar dynamic-height loop).
@@ -1,4 +1,4 @@
1
- import { ProjectChannel, WindowChannel, SettingsChannel, PopoverChannel, ToolbarChannel, WorkbenchSettingsChannel, EditorChannel, ViewChannel, } from '../../../shared/ipc-channels.js';
1
+ import { ProjectChannel, WindowChannel, SettingsChannel, PopoverChannel, WorkbenchSettingsChannel, EditorChannel, ViewChannel, } from '../../../shared/ipc-channels.js';
2
2
  /** Safely resolve a WebContents, skipping destroyed / missing targets. */
3
3
  function liveWebContents(wc) {
4
4
  if (!wc)
@@ -27,21 +27,12 @@ export function createRendererNotifier(ctx) {
27
27
  windowNavigateBack() {
28
28
  sendToMain(WindowChannel.NavigateBack);
29
29
  },
30
- settingsClosed() {
31
- sendToMain(SettingsChannel.Closed);
32
- },
33
- settingsChanged(config) {
34
- sendToMain(SettingsChannel.Changed, config);
35
- },
36
30
  popoverClosed() {
37
31
  sendToMain(PopoverChannel.Closed);
38
32
  },
39
33
  popoverRelaunch(config) {
40
34
  sendToMain(PopoverChannel.Relaunch, config);
41
35
  },
42
- toolbarActionsChanged() {
43
- sendToMain(ToolbarChannel.ActionsChanged);
44
- },
45
36
  hostToolbarHeightChanged(height) {
46
37
  sendToMain(ViewChannel.HostToolbarHeightChanged, height);
47
38
  },
@@ -5,10 +5,11 @@ import { BrowserWindow } from 'electron';
5
5
  * Design source: `packages/devtools/docs/prewarm-webview.md`. WIRED into
6
6
  * native-host via `bridge-router.handleSpawn` (acquire) + `disposeAppSession`
7
7
  * (release / releaseDestroyed), opt-in behind `DIMINA_PREWARM_POOL_SIZE`
8
- * (default OFF). Default-arch (`view-manager.attachSimulator`) is NOT pooled
9
- * its simulator is a `<webview>` tag, which Electron can't reparent a pre-warmed
10
- * WebContents into (doc §5 Phase 4, blocked by that hard limit, not by missing
11
- * work here).
8
+ * (default OFF). Only the SERVICE-HOST window is pooled; the simulator content
9
+ * WebContentsView (`view-manager.attachNativeSimulator`) is created fresh per
10
+ * attach. (The historical `<webview>`-tag default arch was never poolable
11
+ * Electron can't reparent a pre-warmed WebContents into a `<webview>`; doc §5
12
+ * Phase 4 — and that route has since been deleted outright.)
12
13
  *
13
14
  * Lifecycle of a pool entry:
14
15
  * warming — BrowserWindow constructed, page loading