@dxos/plugin-devtools 0.11.1 → 0.12.0-next-2800d0376abcc62d5544afdd744b16b2b960434e

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 (127) hide show
  1. package/dist/lib/{chunk-types.mjs → Devtools.mjs} +5 -14
  2. package/dist/lib/Devtools.mjs.map +1 -0
  3. package/dist/lib/DevtoolsEvents.mjs +15 -0
  4. package/dist/lib/DevtoolsEvents.mjs.map +1 -0
  5. package/dist/lib/DevtoolsPlugin.mjs +13 -36
  6. package/dist/lib/DevtoolsPlugin.mjs.map +1 -1
  7. package/dist/lib/capabilities.mjs +39 -5
  8. package/dist/lib/capabilities.mjs.map +1 -1
  9. package/dist/lib/capabilities.node.mjs +34 -0
  10. package/dist/lib/capabilities.node.mjs.map +1 -0
  11. package/dist/lib/capabilities.workerd.mjs +30 -0
  12. package/dist/lib/capabilities.workerd.mjs.map +1 -0
  13. package/dist/lib/chunk-CliPanel.mjs +103 -0
  14. package/dist/lib/chunk-CliPanel.mjs.map +1 -0
  15. package/dist/lib/chunk-DebugGraph.mjs +2 -2
  16. package/dist/lib/chunk-DebugGraph.mjs.map +1 -1
  17. package/dist/lib/chunk-DevtoolsOverviewContainer.mjs +14 -13
  18. package/dist/lib/chunk-DevtoolsOverviewContainer.mjs.map +1 -1
  19. package/dist/lib/chunk-GithubPanel.mjs +36 -30
  20. package/dist/lib/chunk-GithubPanel.mjs.map +1 -1
  21. package/dist/lib/chunk-RegistryPanel.mjs +2 -2
  22. package/dist/lib/chunk-RegistryPanel.mjs.map +1 -1
  23. package/dist/lib/chunk-app-graph-builder.mjs +66 -50
  24. package/dist/lib/chunk-app-graph-builder.mjs.map +1 -1
  25. package/dist/lib/chunk-react-context.mjs +4 -3
  26. package/dist/lib/chunk-react-context.mjs.map +1 -1
  27. package/dist/lib/chunk-react-surface.mjs +35 -28
  28. package/dist/lib/chunk-react-surface.mjs.map +1 -1
  29. package/dist/lib/chunk-rolldown-runtime.mjs +13 -0
  30. package/dist/lib/containers.mjs +2 -1
  31. package/dist/lib/containers.mjs.map +1 -1
  32. package/dist/lib/index.mjs +4 -3
  33. package/dist/lib/meta.mjs +29 -1
  34. package/dist/lib/meta.mjs.map +1 -0
  35. package/dist/lib/plugin.mjs +6 -5
  36. package/dist/lib/plugin.mjs.map +1 -1
  37. package/dist/lib/translations.mjs +1 -0
  38. package/dist/lib/translations.mjs.map +1 -1
  39. package/dist/lib/types.mjs +3 -2
  40. package/dist/types/src/DevtoolsPlugin.d.ts +36 -3
  41. package/dist/types/src/DevtoolsPlugin.d.ts.map +1 -1
  42. package/dist/types/src/capabilities/DevtoolsSurfaces.d.ts.map +1 -1
  43. package/dist/types/src/capabilities/app-graph-builder.d.ts +2 -2
  44. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  45. package/dist/types/src/capabilities/gen/node.d.ts +8 -0
  46. package/dist/types/src/capabilities/gen/node.d.ts.map +1 -0
  47. package/dist/types/src/capabilities/gen/workerd.d.ts +8 -0
  48. package/dist/types/src/capabilities/gen/workerd.d.ts.map +1 -0
  49. package/dist/types/src/capabilities/index.d.ts +7 -4
  50. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  51. package/dist/types/src/capabilities/react-context.d.ts +2 -2
  52. package/dist/types/src/capabilities/react-context.d.ts.map +1 -1
  53. package/dist/types/src/capabilities/react-surface.d.ts +2 -2
  54. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  55. package/dist/types/src/containers/CliPanel/CliPanel.d.ts +6 -0
  56. package/dist/types/src/containers/CliPanel/CliPanel.d.ts.map +1 -0
  57. package/dist/types/src/containers/CliPanel/CliPanel.stories.d.ts +89 -0
  58. package/dist/types/src/containers/CliPanel/CliPanel.stories.d.ts.map +1 -0
  59. package/dist/types/src/containers/CliPanel/index.d.ts +2 -0
  60. package/dist/types/src/containers/CliPanel/index.d.ts.map +1 -0
  61. package/dist/types/src/containers/CliPanel/useCliApp.d.ts +29 -0
  62. package/dist/types/src/containers/CliPanel/useCliApp.d.ts.map +1 -0
  63. package/dist/types/src/containers/DebugGraph/DebugGraph.d.ts +2 -2
  64. package/dist/types/src/containers/DebugGraph/DebugGraph.d.ts.map +1 -1
  65. package/dist/types/src/containers/GithubPanel/GithubComponent.d.ts +9 -4
  66. package/dist/types/src/containers/GithubPanel/GithubComponent.d.ts.map +1 -1
  67. package/dist/types/src/containers/GithubPanel/GithubComponent.stories.d.ts +6 -4
  68. package/dist/types/src/containers/GithubPanel/GithubComponent.stories.d.ts.map +1 -1
  69. package/dist/types/src/containers/index.d.ts +1 -0
  70. package/dist/types/src/containers/index.d.ts.map +1 -1
  71. package/dist/types/src/index.d.ts +3 -2
  72. package/dist/types/src/index.d.ts.map +1 -1
  73. package/dist/types/src/plugin.d.ts +2 -1
  74. package/dist/types/src/plugin.d.ts.map +1 -1
  75. package/dist/types/src/plugin.test.d.ts +2 -0
  76. package/dist/types/src/plugin.test.d.ts.map +1 -0
  77. package/dist/types/src/translations.d.ts +6 -4
  78. package/dist/types/src/translations.d.ts.map +1 -1
  79. package/dist/types/src/types/Devtools.d.ts +1 -0
  80. package/dist/types/src/types/Devtools.d.ts.map +1 -1
  81. package/dist/types/src/types/DevtoolsEvents.d.ts +8 -0
  82. package/dist/types/src/types/DevtoolsEvents.d.ts.map +1 -0
  83. package/dist/types/src/types/index.d.ts +1 -0
  84. package/dist/types/src/types/index.d.ts.map +1 -1
  85. package/dist/types/tsconfig.tsbuildinfo +1 -1
  86. package/package.json +73 -74
  87. package/src/DevtoolsPlugin.ts +15 -0
  88. package/src/capabilities/DevtoolsSurfaces.tsx +9 -4
  89. package/src/capabilities/app-graph-builder.ts +72 -49
  90. package/src/capabilities/gen/node.ts +49 -0
  91. package/src/capabilities/gen/workerd.ts +44 -0
  92. package/src/capabilities/index.ts +50 -4
  93. package/src/capabilities/react-context.tsx +3 -2
  94. package/src/capabilities/react-surface.ts +11 -5
  95. package/src/containers/CliPanel/CliPanel.stories.tsx +75 -0
  96. package/src/containers/CliPanel/CliPanel.tsx +45 -0
  97. package/src/containers/CliPanel/index.ts +5 -0
  98. package/src/containers/CliPanel/useCliApp.ts +103 -0
  99. package/src/containers/DebugGraph/DebugGraph.tsx +3 -3
  100. package/src/containers/GithubPanel/GithubComponent.tsx +13 -15
  101. package/src/containers/RegistryPanel/RegistryPanel.tsx +1 -1
  102. package/src/containers/index.ts +1 -0
  103. package/src/index.ts +3 -2
  104. package/src/meta.ts +1 -1
  105. package/src/{DevtoolsPlugin.test.ts → plugin.test.ts} +5 -4
  106. package/src/plugin.tsx +20 -0
  107. package/src/translations.ts +1 -0
  108. package/src/types/Devtools.ts +1 -0
  109. package/src/types/DevtoolsEvents.ts +16 -0
  110. package/src/types/index.ts +1 -0
  111. package/dist/lib/DevtoolsPlugin.node.mjs +0 -10
  112. package/dist/lib/DevtoolsPlugin.node.mjs.map +0 -1
  113. package/dist/lib/DevtoolsPlugin.workerd.mjs +0 -8
  114. package/dist/lib/DevtoolsPlugin.workerd.mjs.map +0 -1
  115. package/dist/lib/chunk-meta.mjs +0 -30
  116. package/dist/lib/chunk-meta.mjs.map +0 -1
  117. package/dist/lib/chunk-types.mjs.map +0 -1
  118. package/dist/types/src/DevtoolsPlugin.node.d.ts +0 -4
  119. package/dist/types/src/DevtoolsPlugin.node.d.ts.map +0 -1
  120. package/dist/types/src/DevtoolsPlugin.test.d.ts +0 -2
  121. package/dist/types/src/DevtoolsPlugin.test.d.ts.map +0 -1
  122. package/dist/types/src/DevtoolsPlugin.workerd.d.ts +0 -4
  123. package/dist/types/src/DevtoolsPlugin.workerd.d.ts.map +0 -1
  124. package/src/DevtoolsPlugin.node.ts +0 -16
  125. package/src/DevtoolsPlugin.tsx +0 -54
  126. package/src/DevtoolsPlugin.workerd.ts +0 -11
  127. package/src/plugin.ts +0 -9
@@ -1,20 +1,10 @@
1
+ import { t as __exportAll } from "./chunk-rolldown-runtime.mjs";
1
2
  import { meta } from "#meta";
2
- //#region \0rolldown/runtime.js
3
- var __defProp = Object.defineProperty;
4
- var __exportAll = (all, no_symbols) => {
5
- let target = {};
6
- for (var name in all) __defProp(target, name, {
7
- get: all[name],
8
- enumerable: true
9
- });
10
- if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
11
- return target;
12
- };
13
- //#endregion
14
3
  //#region src/types/Devtools.ts
15
4
  var Devtools_exports = /* @__PURE__ */ __exportAll({
16
5
  Agent: () => Agent,
17
6
  AppGraph: () => AppGraph,
7
+ Cli: () => Cli,
18
8
  Client: () => Client,
19
9
  Echo: () => Echo,
20
10
  Edge: () => Edge,
@@ -34,6 +24,7 @@ var devtoolsId = `${meta.profile.key}.devtools`;
34
24
  var id = devtoolsId;
35
25
  var AppGraph = `${devtoolsId}.appGraph`;
36
26
  var ToolsExplorer = `${devtoolsId}.toolsExplorer`;
27
+ var Cli = `${devtoolsId}.cli`;
37
28
  var Client;
38
29
  (function(_Client) {
39
30
  _Client.id = `${devtoolsId}.client`;
@@ -87,6 +78,6 @@ var Edge;
87
78
  _Edge.Testing = `${Edge.id}.testing`;
88
79
  })(Edge || (Edge = {}));
89
80
  //#endregion
90
- export { Devtools_exports as t };
81
+ export { Agent, AppGraph, Cli, Client, Echo, Edge, Halo, Mesh, ToolsExplorer, id, nodeId, Devtools_exports as t };
91
82
 
92
- //# sourceMappingURL=chunk-types.mjs.map
83
+ //# sourceMappingURL=Devtools.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Devtools.mjs","names":[],"sources":["../../src/types/Devtools.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport { meta } from '#meta';\n\n/**\n * Extracts the last dot-separated segment of a Devtools namespaced ID string.\n * Use this as the node segment `id` when building app-graph nodes whose `data`\n * value is one of the other constants in this namespace.\n */\nexport const nodeId = (fullId: string): string => fullId.split('.').at(-1) ?? '';\n\nconst devtoolsId = `${meta.profile.key}.devtools`;\n\nexport const id = devtoolsId;\nexport const AppGraph = `${devtoolsId}.appGraph`;\nexport const ToolsExplorer = `${devtoolsId}.toolsExplorer`;\nexport const Cli = `${devtoolsId}.cli`;\n\nexport namespace Client {\n export const id = `${devtoolsId}.client`;\n export const Config = `${Client.id}.config`;\n export const Storage = `${Client.id}.storage`;\n export const Sqlite = `${Client.id}.sqlite`;\n export const Logs = `${Client.id}.logs`;\n export const Diagnostics = `${Client.id}.diagnostics`;\n}\n\nexport namespace Halo {\n export const id = `${devtoolsId}.halo`;\n export const Identity = `${Halo.id}.identity`;\n export const Devices = `${Halo.id}.devices`;\n export const Keyring = `${Halo.id}.keyring`;\n export const Credentials = `${Halo.id}.credentials`;\n}\n\nexport namespace Echo {\n export const id = `${devtoolsId}.echo`;\n export const Spaces = `${Echo.id}.spaces`;\n export const Space = `${Echo.id}.space`;\n export const Feeds = `${Echo.id}.feeds`;\n export const Objects = `${Echo.id}.objects`;\n export const Schema = `${Echo.id}.schema`;\n export const Registry = `${Echo.id}.registry`;\n export const Automerge = `${Echo.id}.automerge`;\n export const Queues = `${Echo.id}.queues`;\n export const Members = `${Echo.id}.members`;\n export const Metadata = `${Echo.id}.metadata`;\n}\n\nexport namespace Mesh {\n export const id = `${devtoolsId}.mesh`;\n export const Signal = `${Mesh.id}.signal`;\n export const Swarm = `${Mesh.id}.swarm`;\n export const Network = `${Mesh.id}.network`;\n}\n\nexport namespace Agent {\n export const id = `${devtoolsId}.agent`;\n export const Dashboard = `${Agent.id}.dashboard`;\n export const Search = `${Agent.id}.search`;\n}\n\nexport namespace Edge {\n export const id = `${devtoolsId}.edge`;\n export const Dashboard = `${Edge.id}.dashboard`;\n export const Workflows = `${Edge.id}.workflows`;\n export const Traces = `${Edge.id}.traces`;\n export const Testing = `${Edge.id}.testing`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAaA,IAAa,UAAU,WAA2B,OAAO,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK;AAE9E,IAAM,aAAa,GAAG,KAAK,QAAQ,IAAI;AAEvC,IAAa,KAAK;AAClB,IAAa,WAAW,GAAG,WAAW;AACtC,IAAa,gBAAgB,GAAG,WAAW;AAC3C,IAAa,MAAM,GAAG,WAAW;AAE1B,IAAU;CAAV,SAAA,SAAA;CACQ,QAAA,KAAK,GAAG,WAAW;CACnB,QAAA,SAAS,GAAG,OAAO,GAAG;CACtB,QAAA,UAAU,GAAG,OAAO,GAAG;CACvB,QAAA,SAAS,GAAG,OAAO,GAAG;CACtB,QAAA,OAAO,GAAG,OAAO,GAAG;CACpB,QAAA,cAAc,GAAG,OAAO,GAAG;AAC1C,EAAA,CAAA,WAAA,SAAA,CAAA,EAAA;AAEO,IAAU;CAAV,SAAA,OAAA;CACQ,MAAA,KAAK,GAAG,WAAW;CACnB,MAAA,WAAW,GAAG,KAAK,GAAG;CACtB,MAAA,UAAU,GAAG,KAAK,GAAG;CACrB,MAAA,UAAU,GAAG,KAAK,GAAG;CACrB,MAAA,cAAc,GAAG,KAAK,GAAG;AACxC,EAAA,CAAA,SAAA,OAAA,CAAA,EAAA;AAEO,IAAU;CAAV,SAAA,OAAA;CACQ,MAAA,KAAK,GAAG,WAAW;CACnB,MAAA,SAAS,GAAG,KAAK,GAAG;CACpB,MAAA,QAAQ,GAAG,KAAK,GAAG;CACnB,MAAA,QAAQ,GAAG,KAAK,GAAG;CACnB,MAAA,UAAU,GAAG,KAAK,GAAG;CACrB,MAAA,SAAS,GAAG,KAAK,GAAG;CACpB,MAAA,WAAW,GAAG,KAAK,GAAG;CACtB,MAAA,YAAY,GAAG,KAAK,GAAG;CACvB,MAAA,SAAS,GAAG,KAAK,GAAG;CACpB,MAAA,UAAU,GAAG,KAAK,GAAG;CACrB,MAAA,WAAW,GAAG,KAAK,GAAG;AACrC,EAAA,CAAA,SAAA,OAAA,CAAA,EAAA;AAEO,IAAU;CAAV,SAAA,OAAA;CACQ,MAAA,KAAK,GAAG,WAAW;CACnB,MAAA,SAAS,GAAG,KAAK,GAAG;CACpB,MAAA,QAAQ,GAAG,KAAK,GAAG;CACnB,MAAA,UAAU,GAAG,KAAK,GAAG;AACpC,EAAA,CAAA,SAAA,OAAA,CAAA,EAAA;AAEO,IAAU;CAAV,SAAA,QAAA;CACQ,OAAA,KAAK,GAAG,WAAW;CACnB,OAAA,YAAY,GAAG,MAAM,GAAG;CACxB,OAAA,SAAS,GAAG,MAAM,GAAG;AACpC,EAAA,CAAA,UAAA,QAAA,CAAA,EAAA;AAEO,IAAU;CAAV,SAAA,OAAA;CACQ,MAAA,KAAK,GAAG,WAAW;CACnB,MAAA,YAAY,GAAG,KAAK,GAAG;CACvB,MAAA,YAAY,GAAG,KAAK,GAAG;CACvB,MAAA,SAAS,GAAG,KAAK,GAAG;CACpB,MAAA,UAAU,GAAG,KAAK,GAAG;AACpC,EAAA,CAAA,SAAA,OAAA,CAAA,EAAA"}
@@ -0,0 +1,15 @@
1
+ import { t as __exportAll } from "./chunk-rolldown-runtime.mjs";
2
+ import { meta } from "#meta";
3
+ import * as ActivationEvent from "@dxos/app-framework/ActivationEvent";
4
+ //#region src/types/DevtoolsEvents.ts
5
+ var DevtoolsEvents_exports = /* @__PURE__ */ __exportAll({ Start: () => Start });
6
+ /**
7
+ * The feature's start event: the plugin's start-gated modules (and cross-plugin
8
+ * contributions consumed by this feature) activate here. Fired on demand and by the
9
+ * host's idle trickle.
10
+ */
11
+ var Start = ActivationEvent.pluginStart(meta.profile.key);
12
+ //#endregion
13
+ export { Start, DevtoolsEvents_exports as t };
14
+
15
+ //# sourceMappingURL=DevtoolsEvents.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DevtoolsEvents.mjs","names":[],"sources":["../../src/types/DevtoolsEvents.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as ActivationEvent from '@dxos/app-framework/ActivationEvent';\n\nimport { meta } from '#meta';\n\n/**\n * The feature's start event: the plugin's start-gated modules (and cross-plugin\n * contributions consumed by this feature) activate here. Fired on demand and by the\n * host's idle trickle.\n */\nexport const Start = ActivationEvent.pluginStart(meta.profile.key);\n"],"mappings":";;;;;;;;;;AAeA,IAAa,QAAQ,gBAAgB,YAAY,KAAK,QAAQ,GAAG"}
@@ -1,39 +1,16 @@
1
- import { ActivationEvents, Capability, Plugin } from "@dxos/app-framework";
2
- import { meta } from "#meta";
3
- import * as Effect from "effect/Effect";
4
- import { AppPlugin } from "@dxos/app-toolkit";
5
- import { AppGraphBuilder, ReactContext, ReactSurface } from "#capabilities";
6
- import { translations } from "#translations";
1
+ import { t as __exportAll } from "./chunk-rolldown-runtime.mjs";
2
+ import { meta as meta$1 } from "#meta";
3
+ import * as Plugin from "@dxos/app-framework/Plugin";
4
+ //#region src/DevtoolsPlugin.ts
5
+ var DevtoolsPlugin_exports = /* @__PURE__ */ __exportAll({
6
+ make: () => make,
7
+ meta: () => meta
8
+ });
9
+ /** Plugin metadata, available without loading the plugin body. */
10
+ var meta = meta$1;
11
+ /** Constructs the plugin; the body loads on first enable. */
12
+ var make = Plugin.lazy(meta, () => import("#plugin"));
7
13
  //#endregion
8
- //#region src/DevtoolsPlugin.tsx
9
- var DevtoolsPlugin = Plugin.define(meta).pipe(AppPlugin.addAppGraphModule({ activate: AppGraphBuilder }), AppPlugin.addReactContextModule({ activate: ReactContext }), Plugin.addModule({
10
- id: Capability.getModuleTag(ReactSurface) ?? "surfaces",
11
- activatesOn: ActivationEvents.SetupReactSurface,
12
- activate: () => ReactSurface()
13
- }), AppPlugin.addTranslationsModule({ translations }), Plugin.addModule({
14
- id: "setup-devtools",
15
- activatesOn: ActivationEvents.Startup,
16
- activate: () => Effect.sync(() => setupDevtools())
17
- }), AppPlugin.addPluginAssetModule({ asset: {
18
- pluginId: meta.profile.key,
19
- path: "PLUGIN.mdl",
20
- content: "---\nid: org.dxos.plugin.devtools\nname: DevtoolsPlugin\nversion: 0.1.0\n---\n\nDeveloper inspector plugin for `DXOS` Composer — structured devtools panels for Client/HALO/ECHO/Mesh/EDGE subsystems, an app-graph inspector, and a tools explorer. Debugging utilities (object generation, wireframe overlays, per-object inspection, stats) live in the sibling `@dxos/plugin-debug`.\n\n## Extensions\n\nThe following extension dialects are used in this document.\nEach extension is defined in the Appendix or resolved via its URI.\n\n| Term | URI |\n|-------------|--------------------------------|\n| `type` | `org.dxos.mdl.type@1.0` |\n| `feat` | `org.dxos.mdl.feat@1.0` |\n| `test` | `org.dxos.mdl.test@1.0` |\n| `component` | `org.dxos.mdl.component@1.0` |\n| `op` | `org.dxos.mdl.op@1.0` |\n\n## Types\n\n```mdl\ntype Settings\n fields:\n wireframe?: boolean # overlay every article/section surface with a labelled border\n traceAll?: boolean # enable verbose operation tracing across all plugins\n```\n\n```mdl\ntype DebugPluginOptions\n fields:\n logStore?: IdbLogStore # shared persistent log store for capturing and downloading logs\n```\n\n```mdl\ntype DebugContextType\n fields:\n running: boolean\n start(cb: TimerCallback, options: TimerOptions): void\n stop(): void\n```\n\n## Components\n\n```mdl\ncomponent DebugSettings\n desc: Settings panel rendered in the plugin-settings article slot; controls wireframe and traceAll toggles and exposes log download.\n props:\n settings: Settings\n logStore?: IdbLogStore\n actions:\n updateSettings(patch: Partial<Settings>)\n downloadLogs()\n```\n\n```mdl\ncomponent DebugStatus\n desc: Status-indicator surface shown in the main toolbar; reflects the generator timer running state.\n state:\n running: boolean\n```\n\n```mdl\ncomponent DevtoolsOverviewContainer\n desc: Deck-companion panel that provides quick access to all devtools sections via a categorised link list.\n layout: |\n ┌─────────────────────────────┐\n │ Client ▸ Config / Storage │\n │ Logs / Diag │\n │ HALO ▸ Identity / Keys │\n │ ECHO ▸ Spaces / Feeds │\n │ Objects / Schema │\n │ Mesh ▸ Signal / Swarm │\n │ EDGE ▸ Dashboard / … │\n └─────────────────────────────┘\n```\n\n```mdl\ncomponent DebugObjectPanel\n desc: Companion panel for any ECHO object that shows raw field values, type info, and DXN.\n props:\n companionTo: string # DXN of the object being inspected\n```\n\n```mdl\ncomponent DebugSpaceObjectsPanel\n desc: Deck-companion panel listing all objects in the active space with their type, ID, and field count.\n props:\n space: Space\n```\n\n```mdl\ncomponent DebugGraph\n desc: Visual representation of the Composer app-graph as a collapsible JSON tree.\n props:\n graph: Graph.Graph\n root: string # node ID used as the traversal root\n```\n\n```mdl\ncomponent SpaceGenerator\n desc: Article view for generating synthetic ECHO objects into a space; controls count, type mix, and relation density.\n props:\n space: Space\n actions:\n generateObjects(count: number, types: string[])\n clear()\n emits:\n onCreateObjects(objects: Obj.Unknown[])\n```\n\n```mdl\ncomponent Wireframe\n desc: Transparent overlay that wraps any article or section surface and renders a labelled border for layout debugging.\n props:\n label: string # \"role:name\" descriptor shown in the corner badge\n object: Obj.Unknown\n classNames?: string\n```\n\n```mdl\ncomponent SchemaTable\n desc: Tabular display of all registered ECHO schemas with typename, fields, and version.\n```\n\n```mdl\ncomponent GithubPanel\n desc: Developer panel linking to open GitHub issues and CI run status for the current build.\n```\n```\n\n## Components (Devtools Panels)\n\nThe following components are thin wrappers around `@dxos/devtools` panel components, each bound to a specific `Devtools.*` node:\n\n| Component | Devtools node | Displays |\n|------------------------|----------------------------|-----------------------------------------|\n| ConfigPanel | Client.Config | Vault config JSON viewer |\n| StoragePanel | Client.Storage | Local storage browser |\n| LoggingPanel | Client.Logs | Live log stream; download via logStore |\n| DiagnosticsPanel | Client.Diagnostics | Client health / metric charts |\n| IdentityPanel | Halo.Identity | Local identity key + device list |\n| DeviceListPanel | Halo.Devices | All devices paired with this identity |\n| KeyringPanel | Halo.Keyring | Raw keyring entries |\n| CredentialsPanel | Halo.Credentials | Credentials held in the active space |\n| SpaceListPanel | Echo.Spaces | All spaces with state + select action |\n| SpaceInfoPanel | Echo.Space | Selected space feeds / pipelines |\n| FeedsPanel | Echo.Feeds | Feed entries for the active space |\n| ObjectsPanel | Echo.Objects | All objects in the active space |\n| SchemaPanel | Echo.Schema | Schemas registered in the active space |\n| AutomergePanel | Echo.Automerge | Automerge document internals |\n| QueuesPanel | Echo.Queues | Pending queue items |\n| MembersPanel | Echo.Members | Space members with last-seen |\n| MetadataPanel | Echo.Metadata | Space/feed metadata blobs |\n| SignalPanel | Mesh.Signal | Signal-server connection state |\n| SwarmPanel | Mesh.Swarm | Active swarm peers |\n| NetworkPanel | Mesh.Network | Full network topology for active space |\n| EdgeDashboardPanel | Edge.Dashboard | EDGE node health / worker stats |\n| WorkflowPanel | Edge.Workflows | Workflow definitions in active space |\n| InvocationTraceContainer | Edge.Traces | Invocation trace timeline from feed |\n| TestingPanel | Edge.Testing | Integration test harness for EDGE |\n| ToolsExplorer | ToolsExplorer | MCP-backed tools explorer |\n\n## Operations\n\nNo first-party operations are defined by DebugPlugin. The plugin invokes `SpaceOperation.AddObject`, `SpaceOperation.Migrate`, `LayoutOperation.Open`, and `ScriptOperation.CreateScript` from other plugins via `useOperationInvoker` inside its surfaces.\n\n## Features\n\n```mdl\nfeat F-1: Devtools Graph Node\n\n req F-1.1:\n when: DebugPlugin is loaded\n then: a \"Devtools\" node appears pinned at the end of each root and space in the nav graph\n\n req F-1.2: The Devtools node contains sub-trees for Client, HALO, ECHO, Mesh, and EDGE categories.\n req F-1.3: An app-graph sub-node renders DebugGraph rooted at the current space or root.\n req F-1.4: A tools-explorer sub-node renders ToolsExplorer connected to the MCP introspect service.\n```\n\n```mdl\nfeat F-2: Object Debug Companion\n\n req F-2.1:\n when: any ECHO object is open in the deck\n then: a \"Debug\" companion tab is injected at the last position\n\n req F-2.2: DebugObjectPanel shows raw object fields, DXN, and typename for the companion target.\n```\n\n```mdl\nfeat F-3: Space Object Explorer\n\n req F-3.1:\n when: user opens the \"Space Objects\" deck companion\n then: DebugSpaceObjectsPanel lists all ECHO objects in the active space\n\n req F-3.2: List updates reactively as objects are added or removed.\n```\n\n```mdl\nfeat F-4: Devtools Overview Companion\n\n req F-4.1:\n when: user opens the \"Devtools\" deck companion\n then: DevtoolsOverviewContainer renders a categorised link list to all devtools panels\n\n req F-4.2: Clicking a category link navigates the deck to the corresponding devtools article.\n```\n\n```mdl\nfeat F-5: Space Data Generator\n\n req F-5.1:\n when: user navigates to the debug node under a space\n then: SpaceGenerator is rendered as the article\n\n req F-5.2:\n when: user triggers object generation\n then: synthetic ECHO objects are created via op:SpaceOperation.AddObject in the active collection\n\n req F-5.3: DebugStatus indicator in the toolbar shows a running state while generation is active.\n```\n\n```mdl\nfeat F-6: Wireframe Overlay\n\n req F-6.1:\n when: settings.wireframe is true\n then: Wireframe wraps every article and section surface with a labelled border\n\n req F-6.2:\n when: settings.wireframe is false or unset\n then: no overlay is injected; the Wireframe surface filter returns false immediately\n```\n\n```mdl\nfeat F-7: Log Capture and Download\n\n req F-7.1:\n when: logStore is provided in DebugPluginOptions\n then: LoggingPanel can stream and display captured log entries\n\n req F-7.2:\n when: user clicks download in DebugSettings\n then: captured logs are serialised and offered as a file download via the file uploader capability\n```\n\n```mdl\nfeat F-8: Global Dev Utilities\n\n req F-8.1:\n when: DebugPlugin activates\n then: globalThis.composer.changeStorageVersionInMetadata is registered for manual storage-migration testing\n\n req F-8.2: The function destroys the client, rewrites the storage version metadata, and reloads the page.\n```\n\n## Acceptance\n\n```mdl\ntest T-1: Devtools node appears in nav graph\n given: Composer loaded with DebugPlugin enabled\n when: user opens the navigation tree\n then:\n - \"Devtools\" node is visible pinned at the end of the root\n - sub-nodes Client, HALO, ECHO, Mesh, EDGE are present\n```\n\n```mdl\ntest T-2: Debug companion on ECHO object\n given: a Document is open in the deck\n when: user clicks the \"Debug\" companion tab\n then:\n - DebugObjectPanel renders with the object's DXN and field map\n```\n\n```mdl\ntest T-3: Wireframe overlay toggle\n given: DebugPlugin settings panel is open\n when: user enables the wireframe toggle\n then:\n - every article and section surface shows a labelled border\n when: user disables the wireframe toggle\n then:\n - borders are removed immediately\n```\n\n```mdl\ntest T-4: Space object generation\n given: a space with an empty collection is active\n when: user opens the debug space node and generates 10 objects\n then:\n - 10 new objects appear in the active collection\n - DebugStatus shows \"running\" while generation is in progress\n```\n\n```mdl\ntest T-5: Log download\n given: logStore is configured and some log entries have been captured\n when: user clicks \"Download Logs\" in DebugSettings\n then:\n - a file download is triggered containing the serialised log entries\n```\n\n---\n\n## Appendix: Extension Definitions\n\n```mdl\next type\n uri: org.dxos.mdl.type@1.0\n desc: A named data structure with typed fields and optional literals.\n fields:\n desc?: Prose\n fields?: FieldMap\n literals?: UnionList\n extends?: TypeRef[]\n```\n\n```mdl\next feat\n uri: org.dxos.mdl.feat@1.0\n desc: A named feature grouping one or more requirements.\n fields:\n desc?: Prose\n req: RequirementList\n nesting: self\n```\n\n```mdl\next test\n uri: org.dxos.mdl.test@1.0\n desc: An acceptance scenario expressed as given / when / then steps.\n fields:\n given?: Step | Step[]\n when?: Step | Step[]\n then: Step | Step[]\n tags?: TagList\n```\n\n```mdl\next component\n uri: org.dxos.mdl.component@1.0\n desc: A UI component with props, internal state, slots, actions, and events.\n fields:\n desc?: Prose\n props?: FieldMap\n state?: FieldMap\n slots?: FieldMap\n actions?: ActionMap\n emits?: EventMap\n layout?: CodeBlock\n```\n\n```mdl\next op\n uri: org.dxos.mdl.op@1.0\n desc: |\n A named operation with typed inputs, outputs, and declared errors.\n Pure ops have no effects or requires. Effectful ops declare both.\n fields:\n desc?: Prose\n input?: FieldMap\n output?: TypeExpr\n errors?: ErrorMap\n effects?: EffectList\n requires?: ServiceList\n note?: Prose\n```\n",
21
- mimeType: "application/x-mdl"
22
- } }), Plugin.make);
23
- var setupDevtools = () => {
24
- globalThis.composer ??= {};
25
- globalThis.composer.changeStorageVersionInMetadata = async (version) => {
26
- const { changeStorageVersionInMetadata } = await import("@dxos/client-services/testing");
27
- const { createStorageObjects } = await import("@dxos/client-services");
28
- const client = window.dxos.client;
29
- const config = client.config;
30
- await client.destroy();
31
- const { storage } = createStorageObjects(config.values?.runtime?.client?.storage ?? {});
32
- await changeStorageVersionInMetadata(storage, version);
33
- location.pathname = "/";
34
- };
35
- };
36
- //#endregion
37
- export { DevtoolsPlugin, DevtoolsPlugin as default };
14
+ export { make, meta, DevtoolsPlugin_exports as t };
38
15
 
39
16
  //# sourceMappingURL=DevtoolsPlugin.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"DevtoolsPlugin.mjs","names":[],"sources":["../../src/DevtoolsPlugin.tsx"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { ActivationEvents, Capability, Plugin } from '@dxos/app-framework';\nimport { AppPlugin } from '@dxos/app-toolkit';\nimport { type Client } from '@dxos/react-client';\n\nimport { AppGraphBuilder, ReactContext, ReactSurface } from '#capabilities';\nimport { meta } from '#meta';\nimport { translations } from '#translations';\n\n// eslint-disable-next-line import/no-relative-packages\nimport pluginSpec from '../PLUGIN.mdl?raw';\n\nexport const DevtoolsPlugin = Plugin.define(meta).pipe(\n AppPlugin.addAppGraphModule({ activate: AppGraphBuilder }),\n AppPlugin.addReactContextModule({ activate: ReactContext }),\n Plugin.addModule({\n id: Capability.getModuleTag(ReactSurface) ?? 'surfaces',\n activatesOn: ActivationEvents.SetupReactSurface,\n activate: () => ReactSurface(),\n }),\n AppPlugin.addTranslationsModule({ translations }),\n Plugin.addModule({\n id: 'setup-devtools',\n activatesOn: ActivationEvents.Startup,\n activate: () => Effect.sync(() => setupDevtools()),\n }),\n AppPlugin.addPluginAssetModule({\n asset: { pluginId: meta.profile.key, path: 'PLUGIN.mdl', content: pluginSpec, mimeType: 'application/x-mdl' },\n }),\n Plugin.make,\n);\n\nconst setupDevtools = () => {\n (globalThis as any).composer ??= {};\n\n // Used to test how composer handles breaking protocol changes.\n (globalThis as any).composer.changeStorageVersionInMetadata = async (version: number) => {\n const { changeStorageVersionInMetadata } = await import('@dxos/client-services/testing');\n const { createStorageObjects } = await import('@dxos/client-services');\n const client: Client = (window as any).dxos.client;\n const config = client.config;\n await client.destroy();\n const { storage } = createStorageObjects(config.values?.runtime?.client?.storage ?? {});\n await changeStorageVersionInMetadata(storage, version);\n location.pathname = '/';\n };\n};\n\nexport default DevtoolsPlugin;\n"],"mappings":";;;;;;;;AAiBA,IAAa,iBAAiB,OAAO,OAAO,IAAI,CAAC,CAAC,KAChD,UAAU,kBAAkB,EAAE,UAAU,gBAAgB,CAAC,GACzD,UAAU,sBAAsB,EAAE,UAAU,aAAa,CAAC,GAC1D,OAAO,UAAU;CACf,IAAI,WAAW,aAAa,YAAY,KAAK;CAC7C,aAAa,iBAAiB;CAC9B,gBAAgB,aAAa;AAC/B,CAAC,GACD,UAAU,sBAAsB,EAAE,aAAa,CAAC,GAChD,OAAO,UAAU;CACf,IAAI;CACJ,aAAa,iBAAiB;CAC9B,gBAAgB,OAAO,WAAW,cAAc,CAAC;AACnD,CAAC,GACD,UAAU,qBAAqB,EAC7B,OAAO;CAAE,UAAU,KAAK,QAAQ;CAAK,MAAM;CAAc,SAAS;CAAY,UAAU;AAAoB,EAC9G,CAAC,GACD,OAAO,IACT;AAEA,IAAM,sBAAsB;CAC1B,WAAoB,aAAa,CAAC;CAGlC,WAAoB,SAAS,iCAAiC,OAAO,YAAoB;EACvF,MAAM,EAAE,mCAAmC,MAAM,OAAO;EACxD,MAAM,EAAE,yBAAyB,MAAM,OAAO;EAC9C,MAAM,SAAkB,OAAe,KAAK;EAC5C,MAAM,SAAS,OAAO;EACtB,MAAM,OAAO,QAAQ;EACrB,MAAM,EAAE,YAAY,qBAAqB,OAAO,QAAQ,SAAS,QAAQ,WAAW,CAAC,CAAC;EACtF,MAAM,+BAA+B,SAAS,OAAO;EACrD,SAAS,WAAW;CACtB;AACF"}
1
+ {"version":3,"file":"DevtoolsPlugin.mjs","names":[],"sources":["../../src/DevtoolsPlugin.ts"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Plugin from '@dxos/app-framework/Plugin';\n\nimport { meta as pluginMeta } from '#meta';\n\n/** Plugin metadata, available without loading the plugin body. */\nexport const meta = pluginMeta;\n\n/** Constructs the plugin; the body loads on first enable. */\nexport const make = Plugin.lazy(meta, () => import('#plugin'));\n"],"mappings":";;;;;;;;;AAWA,IAAa,OAAO;;AAGpB,IAAa,OAAO,OAAO,KAAK,YAAY,OAAO,UAAU"}
@@ -1,9 +1,43 @@
1
- import { Capability } from "@dxos/app-framework";
1
+ import { create } from "@bufbuild/protobuf";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Capability from "@dxos/app-framework/Capability";
4
+ import * as AppCapability from "@dxos/app-toolkit/AppCapability";
5
+ import { Runtime_Client_StorageSchema } from "@dxos/protocols/buf/dxos/config_pb";
6
+ import { translations } from "#translations";
7
+ import * as AppCapabilities from "@dxos/app-toolkit/AppCapabilities";
8
+ import { meta } from "#meta";
9
+ //#region PLUGIN.mdl?raw
10
+ var PLUGIN_default = "---\nid: org.dxos.plugin.devtools\nname: DevtoolsPlugin\nversion: 0.1.0\n---\n\nDeveloper inspector plugin for `DXOS` Composer — structured devtools panels for Client/HALO/ECHO/Mesh/EDGE subsystems, an app-graph inspector, and a tools explorer. Debugging utilities (object generation, wireframe overlays, per-object inspection, stats) live in the sibling `@dxos/plugin-debug`.\n\n## Extensions\n\nThe following extension dialects are used in this document.\nEach extension is defined in the Appendix or resolved via its URI.\n\n| Term | URI |\n|-------------|--------------------------------|\n| `type` | `org.dxos.mdl.type@1.0` |\n| `feat` | `org.dxos.mdl.feat@1.0` |\n| `test` | `org.dxos.mdl.test@1.0` |\n| `component` | `org.dxos.mdl.component@1.0` |\n| `op` | `org.dxos.mdl.op@1.0` |\n\n## Types\n\n```mdl\ntype Settings\n fields:\n wireframe?: boolean # overlay every article/section surface with a labelled border\n traceAll?: boolean # enable verbose operation tracing across all plugins\n```\n\n```mdl\ntype DebugPluginOptions\n fields:\n logStore?: IdbLogStore # shared persistent log store for capturing and downloading logs\n```\n\n```mdl\ntype DebugContextType\n fields:\n running: boolean\n start(cb: TimerCallback, options: TimerOptions): void\n stop(): void\n```\n\n## Components\n\n```mdl\ncomponent DebugSettings\n desc: Settings panel rendered in the plugin-settings article slot; controls wireframe and traceAll toggles and exposes log download.\n props:\n settings: Settings\n logStore?: IdbLogStore\n actions:\n updateSettings(patch: Partial<Settings>)\n downloadLogs()\n```\n\n```mdl\ncomponent DebugStatus\n desc: Status-indicator surface shown in the main toolbar; reflects the generator timer running state.\n state:\n running: boolean\n```\n\n```mdl\ncomponent DevtoolsOverviewContainer\n desc: Deck-companion panel that provides quick access to all devtools sections via a categorised link list.\n layout: |\n ┌─────────────────────────────┐\n │ Client ▸ Config / Storage │\n │ Logs / Diag │\n │ HALO ▸ Identity / Keys │\n │ ECHO ▸ Spaces / Feeds │\n │ Objects / Schema │\n │ Mesh ▸ Signal / Swarm │\n │ EDGE ▸ Dashboard / … │\n └─────────────────────────────┘\n```\n\n```mdl\ncomponent DebugObjectPanel\n desc: Companion panel for any ECHO object that shows raw field values, type info, and DXN.\n props:\n companionTo: string # DXN of the object being inspected\n```\n\n```mdl\ncomponent DebugSpaceObjectsPanel\n desc: Deck-companion panel listing all objects in the active space with their type, ID, and field count.\n props:\n space: Space\n```\n\n```mdl\ncomponent DebugGraph\n desc: Visual representation of the Composer app-graph as a collapsible JSON tree.\n props:\n graph: Graph.Graph\n root: string # node ID used as the traversal root\n```\n\n```mdl\ncomponent SpaceGenerator\n desc: Article view for generating synthetic ECHO objects into a space; controls count, type mix, and relation density.\n props:\n space: Space\n actions:\n generateObjects(count: number, types: string[])\n clear()\n emits:\n onCreateObjects(objects: Obj.Unknown[])\n```\n\n```mdl\ncomponent Wireframe\n desc: Transparent overlay that wraps any article or section surface and renders a labelled border for layout debugging.\n props:\n label: string # \"role:name\" descriptor shown in the corner badge\n object: Obj.Unknown\n classNames?: string\n```\n\n```mdl\ncomponent SchemaTable\n desc: Tabular display of all registered ECHO schemas with typename, fields, and version.\n```\n\n```mdl\ncomponent GithubPanel\n desc: Developer panel linking to open GitHub issues and CI run status for the current build.\n```\n```\n\n## Components (Devtools Panels)\n\nThe following components are thin wrappers around `@dxos/devtools` panel components, each bound to a specific `Devtools.*` node:\n\n| Component | Devtools node | Displays |\n|------------------------|----------------------------|-----------------------------------------|\n| ConfigPanel | Client.Config | Vault config JSON viewer |\n| StoragePanel | Client.Storage | Local storage browser |\n| LoggingPanel | Client.Logs | Live log stream; download via logStore |\n| DiagnosticsPanel | Client.Diagnostics | Client health / metric charts |\n| IdentityPanel | Halo.Identity | Local identity key + device list |\n| DeviceListPanel | Halo.Devices | All devices paired with this identity |\n| KeyringPanel | Halo.Keyring | Raw keyring entries |\n| CredentialsPanel | Halo.Credentials | Credentials held in the active space |\n| SpaceListPanel | Echo.Spaces | All spaces with state + select action |\n| SpaceInfoPanel | Echo.Space | Selected space feeds / pipelines |\n| FeedsPanel | Echo.Feeds | Feed entries for the active space |\n| ObjectsPanel | Echo.Objects | All objects in the active space |\n| SchemaPanel | Echo.Schema | Schemas registered in the active space |\n| AutomergePanel | Echo.Automerge | Automerge document internals |\n| QueuesPanel | Echo.Queues | Pending queue items |\n| MembersPanel | Echo.Members | Space members with last-seen |\n| MetadataPanel | Echo.Metadata | Space/feed metadata blobs |\n| SignalPanel | Mesh.Signal | Signal-server connection state |\n| SwarmPanel | Mesh.Swarm | Active swarm peers |\n| NetworkPanel | Mesh.Network | Full network topology for active space |\n| EdgeDashboardPanel | Edge.Dashboard | EDGE node health / worker stats |\n| WorkflowPanel | Edge.Workflows | Workflow definitions in active space |\n| InvocationTraceContainer | Edge.Traces | Invocation trace timeline from feed |\n| TestingPanel | Edge.Testing | Integration test harness for EDGE |\n| ToolsExplorer | ToolsExplorer | MCP-backed tools explorer |\n\n## Operations\n\nNo first-party operations are defined by DebugPlugin. The plugin invokes `SpaceOperation.AddObject`, `SpaceOperation.Migrate`, `LayoutOperation.Open`, and `ScriptOperation.CreateScript` from other plugins via `useOperationInvoker` inside its surfaces.\n\n## Features\n\n```mdl\nfeat F-1: Devtools Graph Node\n\n req F-1.1:\n when: DebugPlugin is loaded\n then: a \"Devtools\" node appears pinned at the end of each root and space in the nav graph\n\n req F-1.2: The Devtools node contains sub-trees for Client, HALO, ECHO, Mesh, and EDGE categories.\n req F-1.3: An app-graph sub-node renders DebugGraph rooted at the current space or root.\n req F-1.4: A tools-explorer sub-node renders ToolsExplorer connected to the MCP introspect service.\n```\n\n```mdl\nfeat F-2: Object Debug Companion\n\n req F-2.1:\n when: any ECHO object is open in the deck\n then: a \"Debug\" companion tab is injected at the last position\n\n req F-2.2: DebugObjectPanel shows raw object fields, DXN, and typename for the companion target.\n```\n\n```mdl\nfeat F-3: Space Object Explorer\n\n req F-3.1:\n when: user opens the \"Space Objects\" deck companion\n then: DebugSpaceObjectsPanel lists all ECHO objects in the active space\n\n req F-3.2: List updates reactively as objects are added or removed.\n```\n\n```mdl\nfeat F-4: Devtools Overview Companion\n\n req F-4.1:\n when: user opens the \"Devtools\" deck companion\n then: DevtoolsOverviewContainer renders a categorised link list to all devtools panels\n\n req F-4.2: Clicking a category link navigates the deck to the corresponding devtools article.\n```\n\n```mdl\nfeat F-5: Space Data Generator\n\n req F-5.1:\n when: user navigates to the debug node under a space\n then: SpaceGenerator is rendered as the article\n\n req F-5.2:\n when: user triggers object generation\n then: synthetic ECHO objects are created via op:SpaceOperation.AddObject in the active collection\n\n req F-5.3: DebugStatus indicator in the toolbar shows a running state while generation is active.\n```\n\n```mdl\nfeat F-6: Wireframe Overlay\n\n req F-6.1:\n when: settings.wireframe is true\n then: Wireframe wraps every article and section surface with a labelled border\n\n req F-6.2:\n when: settings.wireframe is false or unset\n then: no overlay is injected; the Wireframe surface filter returns false immediately\n```\n\n```mdl\nfeat F-7: Log Capture and Download\n\n req F-7.1:\n when: logStore is provided in DebugPluginOptions\n then: LoggingPanel can stream and display captured log entries\n\n req F-7.2:\n when: user clicks download in DebugSettings\n then: captured logs are serialised and offered as a file download via the file uploader capability\n```\n\n```mdl\nfeat F-8: Global Dev Utilities\n\n req F-8.1:\n when: DebugPlugin activates\n then: globalThis.composer.changeStorageVersionInMetadata is registered for manual storage-migration testing\n\n req F-8.2: The function destroys the client, rewrites the storage version metadata, and reloads the page.\n```\n\n## Acceptance\n\n```mdl\ntest T-1: Devtools node appears in nav graph\n given: Composer loaded with DebugPlugin enabled\n when: user opens the navigation tree\n then:\n - \"Devtools\" node is visible pinned at the end of the root\n - sub-nodes Client, HALO, ECHO, Mesh, EDGE are present\n```\n\n```mdl\ntest T-2: Debug companion on ECHO object\n given: a Document is open in the deck\n when: user clicks the \"Debug\" companion tab\n then:\n - DebugObjectPanel renders with the object's DXN and field map\n```\n\n```mdl\ntest T-3: Wireframe overlay toggle\n given: DebugPlugin settings panel is open\n when: user enables the wireframe toggle\n then:\n - every article and section surface shows a labelled border\n when: user disables the wireframe toggle\n then:\n - borders are removed immediately\n```\n\n```mdl\ntest T-4: Space object generation\n given: a space with an empty collection is active\n when: user opens the debug space node and generates 10 objects\n then:\n - 10 new objects appear in the active collection\n - DebugStatus shows \"running\" while generation is in progress\n```\n\n```mdl\ntest T-5: Log download\n given: logStore is configured and some log entries have been captured\n when: user clicks \"Download Logs\" in DebugSettings\n then:\n - a file download is triggered containing the serialised log entries\n```\n\n---\n\n## Appendix: Extension Definitions\n\n```mdl\next type\n uri: org.dxos.mdl.type@1.0\n desc: A named data structure with typed fields and optional literals.\n fields:\n desc?: Prose\n fields?: FieldMap\n literals?: UnionList\n extends?: TypeRef[]\n```\n\n```mdl\next feat\n uri: org.dxos.mdl.feat@1.0\n desc: A named feature grouping one or more requirements.\n fields:\n desc?: Prose\n req: RequirementList\n nesting: self\n```\n\n```mdl\next test\n uri: org.dxos.mdl.test@1.0\n desc: An acceptance scenario expressed as given / when / then steps.\n fields:\n given?: Step | Step[]\n when?: Step | Step[]\n then: Step | Step[]\n tags?: TagList\n```\n\n```mdl\next component\n uri: org.dxos.mdl.component@1.0\n desc: A UI component with props, internal state, slots, actions, and events.\n fields:\n desc?: Prose\n props?: FieldMap\n state?: FieldMap\n slots?: FieldMap\n actions?: ActionMap\n emits?: EventMap\n layout?: CodeBlock\n```\n\n```mdl\next op\n uri: org.dxos.mdl.op@1.0\n desc: |\n A named operation with typed inputs, outputs, and declared errors.\n Pure ops have no effects or requires. Effectful ops declare both.\n fields:\n desc?: Prose\n input?: FieldMap\n output?: TypeExpr\n errors?: ErrorMap\n effects?: EffectList\n requires?: ServiceList\n note?: Prose\n```\n";
11
+ //#endregion
2
12
  //#region src/capabilities/index.ts
3
- var AppGraphBuilder = Capability.lazy("AppGraphBuilder", () => import("./chunk-app-graph-builder.mjs"));
4
- var ReactContext = Capability.lazy("ReactContext", () => import("./chunk-react-context.mjs"));
5
- var ReactSurface = Capability.lazy("ReactSurface", () => import("./chunk-react-surface.mjs"));
13
+ var AppGraphBuilder = AppCapability.appGraphBuilder(() => import("./chunk-app-graph-builder.mjs"), {
14
+ requires: [AppCapabilities.AppGraph],
15
+ environments: ["node"]
16
+ });
17
+ var ReactContext = AppCapability.reactContext(() => import("./chunk-react-context.mjs"));
18
+ var ReactSurface = AppCapability.surface(() => import("./chunk-react-surface.mjs"), { roles: ["org.dxos.role.article", "org.dxos.role.deckCompanion.devtoolsOverview"] });
19
+ var SetupDevtools = Capability.inlineModule("setup-devtools", { provides: [] }, () => Effect.sync(() => setupDevtools()));
20
+ var Translations = AppCapability.translations(translations);
21
+ var PluginAsset = AppCapability.pluginAsset({
22
+ pluginId: meta.profile.key,
23
+ path: "PLUGIN.mdl",
24
+ content: PLUGIN_default,
25
+ mimeType: "application/x-mdl"
26
+ });
27
+ var setupDevtools = () => {
28
+ globalThis.composer ??= {};
29
+ globalThis.composer.changeStorageVersionInMetadata = async (version) => {
30
+ const { changeStorageVersionInMetadata } = await import("@dxos/client-services/testing");
31
+ const { createStorageObjects } = await import("@dxos/client-services");
32
+ const client = window.dxos.client;
33
+ const config = client.config;
34
+ await client.destroy();
35
+ const { storage } = createStorageObjects(config.values?.runtime?.client?.storage ?? create(Runtime_Client_StorageSchema, {}));
36
+ await changeStorageVersionInMetadata(storage, version);
37
+ location.pathname = "/";
38
+ };
39
+ };
6
40
  //#endregion
7
- export { AppGraphBuilder, ReactContext, ReactSurface };
41
+ export { AppGraphBuilder, PluginAsset, ReactContext, ReactSurface, SetupDevtools, Translations };
8
42
 
9
43
  //# sourceMappingURL=capabilities.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.mjs","names":[],"sources":["../../src/capabilities/index.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Capability } from '@dxos/app-framework';\n\nexport const AppGraphBuilder = Capability.lazy('AppGraphBuilder', () => import('./app-graph-builder'));\nexport const ReactContext = Capability.lazy('ReactContext', () => import('./react-context'));\nexport const ReactSurface = Capability.lazy('ReactSurface', () => import('./react-surface'));\n"],"mappings":";;AAMA,IAAa,kBAAkB,WAAW,KAAK,yBAAyB,OAAO,gCAAsB;AACrG,IAAa,eAAe,WAAW,KAAK,sBAAsB,OAAO,4BAAkB;AAC3F,IAAa,eAAe,WAAW,KAAK,sBAAsB,OAAO,4BAAkB"}
1
+ {"version":3,"file":"capabilities.mjs","names":[],"sources":["../../src/capabilities/index.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { create } from '@bufbuild/protobuf';\nimport * as Effect from 'effect/Effect';\n\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport { Runtime_Client_StorageSchema } from '@dxos/protocols/buf/dxos/config_pb';\nimport { type Client } from '@dxos/react-client';\n\nimport { meta } from '#meta';\nimport { translations } from '#translations';\n\n// eslint-disable-next-line import/no-relative-packages\nimport pluginSpec from '../../PLUGIN.mdl?raw';\n\nexport const AppGraphBuilder = AppCapability.appGraphBuilder(() => import('./app-graph-builder'), {\n requires: [AppCapabilities.AppGraph],\n environments: ['node'],\n});\nexport const ReactContext = AppCapability.reactContext(() => import('./react-context'));\nexport const ReactSurface = AppCapability.surface(() => import('./react-surface'), {\n roles: ['org.dxos.role.article', 'org.dxos.role.deckCompanion.devtoolsOverview'],\n});\nexport const SetupDevtools = Capability.inlineModule('setup-devtools', { provides: [] }, () =>\n Effect.sync(() => setupDevtools()),\n);\nexport const Translations = AppCapability.translations(translations);\nexport const PluginAsset = AppCapability.pluginAsset({\n pluginId: meta.profile.key,\n path: 'PLUGIN.mdl',\n content: pluginSpec,\n mimeType: 'application/x-mdl',\n});\n\nconst setupDevtools = () => {\n (globalThis as any).composer ??= {};\n\n // Used to test how composer handles breaking protocol changes.\n (globalThis as any).composer.changeStorageVersionInMetadata = async (version: number) => {\n const { changeStorageVersionInMetadata } = await import('@dxos/client-services/testing');\n const { createStorageObjects } = await import('@dxos/client-services');\n const client: Client = (window as any).dxos.client;\n const config = client.config;\n await client.destroy();\n const { storage } = createStorageObjects(\n config.values?.runtime?.client?.storage ?? create(Runtime_Client_StorageSchema, {}),\n );\n await changeStorageVersionInMetadata(storage, version);\n location.pathname = '/';\n };\n};\n"],"mappings":";;;;;;;;;;;;AAmBA,IAAa,kBAAkB,cAAc,sBAAsB,OAAO,kCAAwB;CAChG,UAAU,CAAC,gBAAgB,QAAQ;CACnC,cAAc,CAAC,MAAM;AACvB,CAAC;AACD,IAAa,eAAe,cAAc,mBAAmB,OAAO,4BAAkB;AACtF,IAAa,eAAe,cAAc,cAAc,OAAO,8BAAoB,EACjF,OAAO,CAAC,yBAAyB,8CAA8C,EACjF,CAAC;AACD,IAAa,gBAAgB,WAAW,aAAa,kBAAkB,EAAE,UAAU,CAAC,EAAE,SACpF,OAAO,WAAW,cAAc,CAAC,CACnC;AACA,IAAa,eAAe,cAAc,aAAa,YAAY;AACnE,IAAa,cAAc,cAAc,YAAY;CACnD,UAAU,KAAK,QAAQ;CACvB,MAAM;CACN,SAAS;CACT,UAAU;AACZ,CAAC;AAED,IAAM,sBAAsB;CAC1B,WAAoB,aAAa,CAAC;CAGlC,WAAoB,SAAS,iCAAiC,OAAO,YAAoB;EACvF,MAAM,EAAE,mCAAmC,MAAM,OAAO;EACxD,MAAM,EAAE,yBAAyB,MAAM,OAAO;EAC9C,MAAM,SAAkB,OAAe,KAAK;EAC5C,MAAM,SAAS,OAAO;EACtB,MAAM,OAAO,QAAQ;EACrB,MAAM,EAAE,YAAY,qBAClB,OAAO,QAAQ,SAAS,QAAQ,WAAW,OAAO,8BAA8B,CAAC,CAAC,CACpF;EACA,MAAM,+BAA+B,SAAS,OAAO;EACrD,SAAS,WAAW;CACtB;AACF"}
@@ -0,0 +1,34 @@
1
+ import { create } from "@bufbuild/protobuf";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Capability from "@dxos/app-framework/Capability";
4
+ import * as AppCapability from "@dxos/app-toolkit/AppCapability";
5
+ import { Runtime_Client_StorageSchema } from "@dxos/protocols/buf/dxos/config_pb";
6
+ import { translations } from "#translations";
7
+ import * as AppCapabilities from "@dxos/app-toolkit/AppCapabilities";
8
+ //#region src/capabilities/gen/node.ts
9
+ var setupDevtools = () => {
10
+ globalThis.composer ??= {};
11
+ globalThis.composer.changeStorageVersionInMetadata = async (version) => {
12
+ const { changeStorageVersionInMetadata } = await import("@dxos/client-services/testing");
13
+ const { createStorageObjects } = await import("@dxos/client-services");
14
+ const client = window.dxos.client;
15
+ const config = client.config;
16
+ await client.destroy();
17
+ const { storage } = createStorageObjects(config.values?.runtime?.client?.storage ?? create(Runtime_Client_StorageSchema, {}));
18
+ await changeStorageVersionInMetadata(storage, version);
19
+ location.pathname = "/";
20
+ };
21
+ };
22
+ var AppGraphBuilder = AppCapability.appGraphBuilder(() => import("./chunk-app-graph-builder.mjs"), {
23
+ requires: [AppCapabilities.AppGraph],
24
+ environments: ["node"]
25
+ });
26
+ var SetupDevtools = Capability.inlineModule("setup-devtools", { provides: [] }, () => Effect.sync(() => setupDevtools()));
27
+ var Translations = AppCapability.translations(translations);
28
+ var PluginAsset = void 0;
29
+ var ReactContext = void 0;
30
+ var ReactSurface = void 0;
31
+ //#endregion
32
+ export { AppGraphBuilder, PluginAsset, ReactContext, ReactSurface, SetupDevtools, Translations };
33
+
34
+ //# sourceMappingURL=capabilities.node.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.node.mjs","names":[],"sources":["../../src/capabilities/gen/node.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// GENERATED by dx-plugin — do not edit. Sliced from ../index.ts for the 'node' condition.\n\nimport { create } from '@bufbuild/protobuf';\nimport * as Effect from 'effect/Effect';\n\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport { Runtime_Client_StorageSchema } from '@dxos/protocols/buf/dxos/config_pb';\nimport { type Client } from '@dxos/react-client';\n\nimport { translations } from '#translations';\n\nconst setupDevtools = () => {\n (globalThis as any).composer ??= {};\n\n // Used to test how composer handles breaking protocol changes.\n (globalThis as any).composer.changeStorageVersionInMetadata = async (version: number) => {\n const { changeStorageVersionInMetadata } = await import('@dxos/client-services/testing');\n const { createStorageObjects } = await import('@dxos/client-services');\n const client: Client = (window as any).dxos.client;\n const config = client.config;\n await client.destroy();\n const { storage } = createStorageObjects(\n config.values?.runtime?.client?.storage ?? create(Runtime_Client_StorageSchema, {}),\n );\n await changeStorageVersionInMetadata(storage, version);\n location.pathname = '/';\n };\n};\n\nexport const AppGraphBuilder = AppCapability.appGraphBuilder(() => import('../app-graph-builder'), {\n requires: [AppCapabilities.AppGraph],\n environments: ['node'],\n});\n\nexport const SetupDevtools = Capability.inlineModule('setup-devtools', { provides: [] }, () =>\n Effect.sync(() => setupDevtools()),\n);\n\nexport const Translations = AppCapability.translations(translations);\n\nexport const PluginAsset = undefined;\nexport const ReactContext = undefined;\nexport const ReactSurface = undefined;\n"],"mappings":";;;;;;;;AAiBA,IAAM,sBAAsB;CAC1B,WAAoB,aAAa,CAAC;CAGlC,WAAoB,SAAS,iCAAiC,OAAO,YAAoB;EACvF,MAAM,EAAE,mCAAmC,MAAM,OAAO;EACxD,MAAM,EAAE,yBAAyB,MAAM,OAAO;EAC9C,MAAM,SAAkB,OAAe,KAAK;EAC5C,MAAM,SAAS,OAAO;EACtB,MAAM,OAAO,QAAQ;EACrB,MAAM,EAAE,YAAY,qBAClB,OAAO,QAAQ,SAAS,QAAQ,WAAW,OAAO,8BAA8B,CAAC,CAAC,CACpF;EACA,MAAM,+BAA+B,SAAS,OAAO;EACrD,SAAS,WAAW;CACtB;AACF;AAEA,IAAa,kBAAkB,cAAc,sBAAsB,OAAO,kCAAyB;CACjG,UAAU,CAAC,gBAAgB,QAAQ;CACnC,cAAc,CAAC,MAAM;AACvB,CAAC;AAED,IAAa,gBAAgB,WAAW,aAAa,kBAAkB,EAAE,UAAU,CAAC,EAAE,SACpF,OAAO,WAAW,cAAc,CAAC,CACnC;AAEA,IAAa,eAAe,cAAc,aAAa,YAAY;AAEnE,IAAa,cAAc,KAAA;AAC3B,IAAa,eAAe,KAAA;AAC5B,IAAa,eAAe,KAAA"}
@@ -0,0 +1,30 @@
1
+ import { create } from "@bufbuild/protobuf";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Capability from "@dxos/app-framework/Capability";
4
+ import * as AppCapability from "@dxos/app-toolkit/AppCapability";
5
+ import { Runtime_Client_StorageSchema } from "@dxos/protocols/buf/dxos/config_pb";
6
+ import { translations } from "#translations";
7
+ //#region src/capabilities/gen/workerd.ts
8
+ var setupDevtools = () => {
9
+ globalThis.composer ??= {};
10
+ globalThis.composer.changeStorageVersionInMetadata = async (version) => {
11
+ const { changeStorageVersionInMetadata } = await import("@dxos/client-services/testing");
12
+ const { createStorageObjects } = await import("@dxos/client-services");
13
+ const client = window.dxos.client;
14
+ const config = client.config;
15
+ await client.destroy();
16
+ const { storage } = createStorageObjects(config.values?.runtime?.client?.storage ?? create(Runtime_Client_StorageSchema, {}));
17
+ await changeStorageVersionInMetadata(storage, version);
18
+ location.pathname = "/";
19
+ };
20
+ };
21
+ var SetupDevtools = Capability.inlineModule("setup-devtools", { provides: [] }, () => Effect.sync(() => setupDevtools()));
22
+ var Translations = AppCapability.translations(translations);
23
+ var AppGraphBuilder = void 0;
24
+ var PluginAsset = void 0;
25
+ var ReactContext = void 0;
26
+ var ReactSurface = void 0;
27
+ //#endregion
28
+ export { AppGraphBuilder, PluginAsset, ReactContext, ReactSurface, SetupDevtools, Translations };
29
+
30
+ //# sourceMappingURL=capabilities.workerd.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.workerd.mjs","names":[],"sources":["../../src/capabilities/gen/workerd.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// GENERATED by dx-plugin — do not edit. Sliced from ../index.ts for the 'workerd' condition.\n\nimport { create } from '@bufbuild/protobuf';\nimport * as Effect from 'effect/Effect';\n\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport { Runtime_Client_StorageSchema } from '@dxos/protocols/buf/dxos/config_pb';\nimport { type Client } from '@dxos/react-client';\n\nimport { translations } from '#translations';\n\nconst setupDevtools = () => {\n (globalThis as any).composer ??= {};\n\n // Used to test how composer handles breaking protocol changes.\n (globalThis as any).composer.changeStorageVersionInMetadata = async (version: number) => {\n const { changeStorageVersionInMetadata } = await import('@dxos/client-services/testing');\n const { createStorageObjects } = await import('@dxos/client-services');\n const client: Client = (window as any).dxos.client;\n const config = client.config;\n await client.destroy();\n const { storage } = createStorageObjects(\n config.values?.runtime?.client?.storage ?? create(Runtime_Client_StorageSchema, {}),\n );\n await changeStorageVersionInMetadata(storage, version);\n location.pathname = '/';\n };\n};\n\nexport const SetupDevtools = Capability.inlineModule('setup-devtools', { provides: [] }, () =>\n Effect.sync(() => setupDevtools()),\n);\n\nexport const Translations = AppCapability.translations(translations);\n\nexport const AppGraphBuilder = undefined;\nexport const PluginAsset = undefined;\nexport const ReactContext = undefined;\nexport const ReactSurface = undefined;\n"],"mappings":";;;;;;;AAgBA,IAAM,sBAAsB;CAC1B,WAAoB,aAAa,CAAC;CAGlC,WAAoB,SAAS,iCAAiC,OAAO,YAAoB;EACvF,MAAM,EAAE,mCAAmC,MAAM,OAAO;EACxD,MAAM,EAAE,yBAAyB,MAAM,OAAO;EAC9C,MAAM,SAAkB,OAAe,KAAK;EAC5C,MAAM,SAAS,OAAO;EACtB,MAAM,OAAO,QAAQ;EACrB,MAAM,EAAE,YAAY,qBAClB,OAAO,QAAQ,SAAS,QAAQ,WAAW,OAAO,8BAA8B,CAAC,CAAC,CACpF;EACA,MAAM,+BAA+B,SAAS,OAAO;EACrD,SAAS,WAAW;CACtB;AACF;AAEA,IAAa,gBAAgB,WAAW,aAAa,kBAAkB,EAAE,UAAU,CAAC,EAAE,SACpF,OAAO,WAAW,cAAc,CAAC,CACnC;AAEA,IAAa,eAAe,cAAc,aAAa,YAAY;AAEnE,IAAa,kBAAkB,KAAA;AAC/B,IAAa,cAAc,KAAA;AAC3B,IAAa,eAAe,KAAA;AAC5B,IAAa,eAAe,KAAA"}
@@ -0,0 +1,103 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Capability from "@dxos/app-framework/Capability";
3
+ import * as Plugin from "@dxos/app-framework/Plugin";
4
+ import { useEffect, useMemo } from "react";
5
+ import * as Capabilities from "@dxos/app-framework/Capabilities";
6
+ import { useCapabilities, usePluginManager } from "@dxos/app-framework/ui";
7
+ import { Placeholder } from "@dxos/devtools";
8
+ import { jsx } from "react/jsx-runtime";
9
+ import { useClient } from "@dxos/react-client";
10
+ import { Panel } from "@dxos/react-ui";
11
+ import { Terminal } from "@dxos/react-ui-terminal";
12
+ import * as Layer from "effect/Layer";
13
+ import * as Command from "effect/unstable/cli/Command";
14
+ import * as Options from "effect/unstable/cli/Flag";
15
+ import * as ActivationEvents from "@dxos/app-framework/ActivationEvents";
16
+ import { CommandConfig } from "@dxos/cli-util";
17
+ import { ClientService, ConfigService } from "@dxos/client";
18
+ import * as Operation from "@dxos/compute/Operation";
19
+ import { EffectEx } from "@dxos/effect";
20
+ //#region src/containers/CliPanel/useCliApp.ts
21
+ var OPERATIONS_UNAVAILABLE = "Operations are not available in the devtools terminal.";
22
+ /**
23
+ * Commands that create objects invoke operations, which this surface has no runtime for. Failing
24
+ * with a stated reason beats the bare "Service not found" a missing layer would produce.
25
+ */
26
+ var operationLayer = Layer.succeed(Operation.Service, {
27
+ invoke: () => Effect.die(OPERATIONS_UNAVAILABLE),
28
+ schedule: () => Effect.die(OPERATIONS_UNAVAILABLE),
29
+ invokePromise: async () => ({ error: /* @__PURE__ */ new Error(OPERATIONS_UNAVAILABLE) })
30
+ });
31
+ /**
32
+ * Builds the `dx` command tree and the services its handlers need.
33
+ *
34
+ * Mounting is the demand signal: command modules are gated on `CommandsRequested`, which nothing
35
+ * else in the app fires, so a plugin's commands stay off the critical path until a terminal opens.
36
+ * The capability is read through its atom, so commands appear as they activate and enabling or
37
+ * disabling a plugin later rebuilds the tree rather than leaving the terminal on the set that
38
+ * existed when it mounted.
39
+ *
40
+ * The root mirrors the binary's, minus the options that only mean something on a filesystem
41
+ * (`--config`, `--profile`); everything else resolves the same way, including `--space-id`
42
+ * defaulting to the first available space.
43
+ *
44
+ * Returns `undefined` until something contributes commands — there is no shell to offer yet.
45
+ */
46
+ var useCliApp = (client) => {
47
+ const manager = usePluginManager();
48
+ const commands = useCapabilities(Capabilities.Command);
49
+ const contributed = useCapabilities(Capabilities.Layer);
50
+ useEffect(() => {
51
+ EffectEx.runDetached(manager.activate(ActivationEvents.CommandsRequested));
52
+ }, [manager]);
53
+ return useMemo(() => {
54
+ const [first, ...rest] = commands;
55
+ if (!first) return;
56
+ const command = Command.make("dx").pipe(Command.withSharedFlags({
57
+ json: Options.boolean("json").pipe(Options.withDescription("JSON output.")),
58
+ verbose: Options.boolean("verbose").pipe(Options.withAlias("v"), Options.withDescription("Verbose output."))
59
+ }), Command.withSubcommands([first, ...rest]), Command.provide((input) => Layer.succeed(CommandConfig, {
60
+ json: "json" in input ? input.json : false,
61
+ verbose: "verbose" in input ? input.verbose : false,
62
+ profile: "default",
63
+ logLevel: "info"
64
+ })));
65
+ const hostLayer = Layer.mergeAll(ClientService.fromClient(client), ConfigService.fromConfig(client.config), Layer.succeed(Plugin.Service, manager), Layer.succeed(Capability.Service, manager.capabilities), operationLayer);
66
+ return {
67
+ command,
68
+ layer: Layer.orDie(Layer.mergeAll(hostLayer, ...contributed))
69
+ };
70
+ }, [
71
+ client,
72
+ manager,
73
+ commands,
74
+ contributed
75
+ ]);
76
+ };
77
+ //#endregion
78
+ //#region src/containers/CliPanel/CliPanel.tsx
79
+ var BOLD = "\x1B[1m";
80
+ var DIM = "\x1B[2m";
81
+ var RESET = "\x1B[0m";
82
+ var BANNER = `${BOLD}DXOS CLI${RESET}\n${DIM}The dx commands, running against this client. Type "help" for the list.${RESET}`;
83
+ /**
84
+ * Runs the `dx` CLI against the client backing this app.
85
+ *
86
+ * The command tree is assembled from the commands the installed plugins contribute, and it and its
87
+ * services are built once per client, so state the handlers hold survives between commands the way
88
+ * it does in a long-lived shell.
89
+ */
90
+ var CliPanel = () => {
91
+ const cli = useCliApp(useClient());
92
+ return /* @__PURE__ */ jsx(Panel.Root, { children: /* @__PURE__ */ jsx(Panel.Content, { children: cli ? /* @__PURE__ */ jsx(Terminal, {
93
+ command: cli.command,
94
+ layer: cli.layer,
95
+ name: "dx",
96
+ banner: BANNER
97
+ }) : /* @__PURE__ */ jsx(Placeholder, { label: "No commands" }) }) });
98
+ };
99
+ CliPanel.displayName = "CliPanel";
100
+ //#endregion
101
+ export { CliPanel, CliPanel as default };
102
+
103
+ //# sourceMappingURL=chunk-CliPanel.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-CliPanel.mjs","names":[],"sources":["../../src/containers/CliPanel/useCliApp.ts","../../src/containers/CliPanel/CliPanel.tsx"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Command from 'effect/unstable/cli/Command';\nimport * as Options from 'effect/unstable/cli/Flag';\nimport { useEffect, useMemo } from 'react';\n\nimport * as ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as Plugin from '@dxos/app-framework/Plugin';\nimport { useCapabilities, usePluginManager } from '@dxos/app-framework/ui';\nimport { CommandConfig, type CommandServices } from '@dxos/cli-util';\nimport { type Client, ClientService, ConfigService } from '@dxos/client';\nimport * as Operation from '@dxos/compute/Operation';\nimport { EffectEx } from '@dxos/effect';\n\nconst OPERATIONS_UNAVAILABLE = 'Operations are not available in the devtools terminal.';\n\n/**\n * Commands that create objects invoke operations, which this surface has no runtime for. Failing\n * with a stated reason beats the bare \"Service not found\" a missing layer would produce.\n */\nconst operationLayer = Layer.succeed(Operation.Service, {\n invoke: () => Effect.die(OPERATIONS_UNAVAILABLE),\n schedule: () => Effect.die(OPERATIONS_UNAVAILABLE),\n invokePromise: async () => ({ error: new Error(OPERATIONS_UNAVAILABLE) }),\n});\n\n/**\n * Builds the `dx` command tree and the services its handlers need.\n *\n * Mounting is the demand signal: command modules are gated on `CommandsRequested`, which nothing\n * else in the app fires, so a plugin's commands stay off the critical path until a terminal opens.\n * The capability is read through its atom, so commands appear as they activate and enabling or\n * disabling a plugin later rebuilds the tree rather than leaving the terminal on the set that\n * existed when it mounted.\n *\n * The root mirrors the binary's, minus the options that only mean something on a filesystem\n * (`--config`, `--profile`); everything else resolves the same way, including `--space-id`\n * defaulting to the first available space.\n *\n * Returns `undefined` until something contributes commands — there is no shell to offer yet.\n */\nexport const useCliApp = (client: Client) => {\n const manager = usePluginManager();\n const commands = useCapabilities(Capabilities.Command);\n const contributed = useCapabilities(Capabilities.Layer);\n\n useEffect(() => {\n EffectEx.runDetached(manager.activate(ActivationEvents.CommandsRequested));\n }, [manager]);\n\n return useMemo(() => {\n // Destructured rather than passed as an array so the non-empty shape `withSubcommands` requires\n // is carried by the type instead of asserted.\n const [first, ...rest] = commands;\n if (!first) {\n return undefined;\n }\n\n const command = Command.make('dx').pipe(\n // Shared so they parse anywhere in the line — a plain command config is only read when `dx`\n // itself is the leaf.\n Command.withSharedFlags({\n json: Options.boolean('json').pipe(Options.withDescription('JSON output.')),\n verbose: Options.boolean('verbose').pipe(Options.withAlias('v'), Options.withDescription('Verbose output.')),\n }),\n Command.withSubcommands([first, ...rest]),\n // After the subcommands so the config reaches them: `provide` wraps the handler it is applied\n // to, and `withSubcommands` replaces that handler with one that dispatches to the children.\n // The input widens to a union across the tree, hence the presence checks.\n Command.provide((input) =>\n Layer.succeed(CommandConfig, {\n json: 'json' in input ? input.json : false,\n verbose: 'verbose' in input ? input.verbose : false,\n profile: 'default',\n logLevel: 'info',\n }),\n ),\n );\n\n // Annotated so a service this host owes is a build error naming it, rather than a\n // \"Service not found\" the first time someone runs the command that needed it.\n const hostLayer: Layer.Layer<CommandServices, never, never> = Layer.mergeAll(\n ClientService.fromClient(client),\n ConfigService.fromConfig(client.config),\n Layer.succeed(Plugin.Service, manager),\n Layer.succeed(Capability.Service, manager.capabilities),\n operationLayer,\n );\n\n // Plugins carry anything further their own commands need. A contributed layer may fail to\n // build, and the shell runs on a fiber with nowhere to report that, so it dies here instead\n // of being smuggled into the terminal as an unhandled error channel.\n const layer = Layer.orDie(Layer.mergeAll(hostLayer, ...contributed));\n\n return { command, layer };\n }, [client, manager, commands, contributed]);\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nimport React from 'react';\n\nimport { Placeholder } from '@dxos/devtools';\nimport { useClient } from '@dxos/react-client';\nimport { Panel } from '@dxos/react-ui';\nimport { Terminal } from '@dxos/react-ui-terminal';\n\nimport { useCliApp } from './useCliApp';\n\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\nconst RESET = '\\x1b[0m';\n\nconst BANNER = `${BOLD}DXOS CLI${RESET}\\n${DIM}The dx commands, running against this client. Type \"help\" for the list.${RESET}`;\n\n/**\n * Runs the `dx` CLI against the client backing this app.\n *\n * The command tree is assembled from the commands the installed plugins contribute, and it and its\n * services are built once per client, so state the handlers hold survives between commands the way\n * it does in a long-lived shell.\n */\nexport const CliPanel = () => {\n const client = useClient();\n const cli = useCliApp(client);\n\n // No ScrollArea: xterm owns its own viewport and scrollback.\n return (\n <Panel.Root>\n <Panel.Content>\n {cli ? (\n <Terminal command={cli.command} layer={cli.layer} name='dx' banner={BANNER} />\n ) : (\n <Placeholder label='No commands' />\n )}\n </Panel.Content>\n </Panel.Root>\n );\n};\n\nCliPanel.displayName = 'CliPanel';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoBA,IAAM,yBAAyB;;;;;AAM/B,IAAM,iBAAiB,MAAM,QAAQ,UAAU,SAAS;CACtD,cAAc,OAAO,IAAI,sBAAsB;CAC/C,gBAAgB,OAAO,IAAI,sBAAsB;CACjD,eAAe,aAAa,EAAE,uBAAO,IAAI,MAAM,sBAAsB,EAAE;AACzE,CAAC;;;;;;;;;;;;;;;;AAiBD,IAAa,aAAa,WAAmB;CAC3C,MAAM,UAAU,iBAAiB;CACjC,MAAM,WAAW,gBAAgB,aAAa,OAAO;CACrD,MAAM,cAAc,gBAAgB,aAAa,KAAK;CAEtD,gBAAgB;EACd,SAAS,YAAY,QAAQ,SAAS,iBAAiB,iBAAiB,CAAC;CAC3E,GAAG,CAAC,OAAO,CAAC;CAEZ,OAAO,cAAc;EAGnB,MAAM,CAAC,OAAO,GAAG,QAAQ;EACzB,IAAI,CAAC,OACH;EAGF,MAAM,UAAU,QAAQ,KAAK,IAAI,CAAC,CAAC,KAGjC,QAAQ,gBAAgB;GACtB,MAAM,QAAQ,QAAQ,MAAM,CAAC,CAAC,KAAK,QAAQ,gBAAgB,cAAc,CAAC;GAC1E,SAAS,QAAQ,QAAQ,SAAS,CAAC,CAAC,KAAK,QAAQ,UAAU,GAAG,GAAG,QAAQ,gBAAgB,iBAAiB,CAAC;EAC7G,CAAC,GACD,QAAQ,gBAAgB,CAAC,OAAO,GAAG,IAAI,CAAC,GAIxC,QAAQ,SAAS,UACf,MAAM,QAAQ,eAAe;GAC3B,MAAM,UAAU,QAAQ,MAAM,OAAO;GACrC,SAAS,aAAa,QAAQ,MAAM,UAAU;GAC9C,SAAS;GACT,UAAU;EACZ,CAAC,CACH,CACF;EAIA,MAAM,YAAwD,MAAM,SAClE,cAAc,WAAW,MAAM,GAC/B,cAAc,WAAW,OAAO,MAAM,GACtC,MAAM,QAAQ,OAAO,SAAS,OAAO,GACrC,MAAM,QAAQ,WAAW,SAAS,QAAQ,YAAY,GACtD,cACF;EAOA,OAAO;GAAE;GAAS,OAFJ,MAAM,MAAM,MAAM,SAAS,WAAW,GAAG,WAAW,CAEhD;EAAM;CAC1B,GAAG;EAAC;EAAQ;EAAS;EAAU;CAAW,CAAC;AAC7C;;;ACzFA,IAAM,OAAO;AACb,IAAM,MAAM;AACZ,IAAM,QAAQ;AAEd,IAAM,SAAS,GAAG,KAAK,UAAU,MAAM,IAAI,IAAI,yEAAyE;;;;;;;;AASxH,IAAa,iBAAiB;CAE5B,MAAM,MAAM,UADG,UACO,CAAM;CAG5B,OACE,oBAAC,MAAM,MAAP,EAAA,UACE,oBAAC,MAAM,SAAP,EAAA,UACG,MACC,oBAAC,UAAD;EAAU,SAAS,IAAI;EAAS,OAAO,IAAI;EAAO,MAAK;EAAK,QAAQ;CAAS,CAAA,IAE7E,oBAAC,aAAD,EAAa,OAAM,cAAe,CAAA,EAEvB,CAAA,EACL,CAAA;AAEhB;AAEA,SAAS,cAAc"}
@@ -1,15 +1,15 @@
1
1
  import "react";
2
- import { Graph } from "@dxos/plugin-graph";
3
2
  import { Tree } from "@dxos/devtools";
4
3
  import { jsx } from "react/jsx-runtime";
5
4
  import { Panel, ScrollArea } from "@dxos/react-ui";
5
+ import * as AppGraph from "@dxos/app-graph/AppGraph";
6
6
  //#region src/containers/DebugGraph/DebugGraph.tsx
7
7
  var DebugGraph = ({ graph, root }) => {
8
8
  return /* @__PURE__ */ jsx(Panel.Root, { children: /* @__PURE__ */ jsx(Panel.Content, {
9
9
  asChild: true,
10
10
  children: /* @__PURE__ */ jsx(ScrollArea.Root, {
11
11
  orientation: "all",
12
- children: /* @__PURE__ */ jsx(ScrollArea.Viewport, { children: /* @__PURE__ */ jsx(Tree, { data: Graph.toJSON(graph, root) }) })
12
+ children: /* @__PURE__ */ jsx(ScrollArea.Viewport, { children: /* @__PURE__ */ jsx(Tree, { data: AppGraph.toJSON(graph, root) }) })
13
13
  })
14
14
  }) });
15
15
  };
@@ -1 +1 @@
1
- {"version":3,"file":"chunk-DebugGraph.mjs","names":[],"sources":["../../src/containers/DebugGraph/DebugGraph.tsx"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport React from 'react';\n\nimport { Tree } from '@dxos/devtools';\nimport { Graph } from '@dxos/plugin-graph';\nimport { Panel, ScrollArea } from '@dxos/react-ui';\n\nexport type DebugGraphProps = { graph: Graph.Graph; root: string };\n\nexport const DebugGraph = ({ graph, root }: DebugGraphProps) => {\n return (\n <Panel.Root>\n <Panel.Content asChild>\n <ScrollArea.Root orientation='all'>\n <ScrollArea.Viewport>\n <Tree data={Graph.toJSON(graph, root)} />\n </ScrollArea.Viewport>\n </ScrollArea.Root>\n </Panel.Content>\n </Panel.Root>\n );\n};\n\nDebugGraph.displayName = 'DebugGraph';\n"],"mappings":";;;;;;AAYA,IAAa,cAAc,EAAE,OAAO,WAA4B;CAC9D,OACE,oBAAC,MAAM,MAAP,EAAA,UACE,oBAAC,MAAM,SAAP;EAAe,SAAA;YACb,oBAAC,WAAW,MAAZ;GAAiB,aAAY;aAC3B,oBAAC,WAAW,UAAZ,EAAA,UACE,oBAAC,MAAD,EAAM,MAAM,MAAM,OAAO,OAAO,IAAI,EAAI,CAAA,EACrB,CAAA;EACN,CAAA;CACJ,CAAA,EACL,CAAA;AAEhB;AAEA,WAAW,cAAc"}
1
+ {"version":3,"file":"chunk-DebugGraph.mjs","names":[],"sources":["../../src/containers/DebugGraph/DebugGraph.tsx"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport React from 'react';\n\nimport * as AppGraph from '@dxos/app-graph/AppGraph';\nimport { Tree } from '@dxos/devtools';\nimport { Panel, ScrollArea } from '@dxos/react-ui';\n\nexport type DebugGraphProps = { graph: AppGraph.Graph; root: string };\n\nexport const DebugGraph = ({ graph, root }: DebugGraphProps) => {\n return (\n <Panel.Root>\n <Panel.Content asChild>\n <ScrollArea.Root orientation='all'>\n <ScrollArea.Viewport>\n <Tree data={AppGraph.toJSON(graph, root)} />\n </ScrollArea.Viewport>\n </ScrollArea.Root>\n </Panel.Content>\n </Panel.Root>\n );\n};\n\nDebugGraph.displayName = 'DebugGraph';\n"],"mappings":";;;;;;AAYA,IAAa,cAAc,EAAE,OAAO,WAA4B;CAC9D,OACE,oBAAC,MAAM,MAAP,EAAA,UACE,oBAAC,MAAM,SAAP;EAAe,SAAA;EACb,UAAA,oBAAC,WAAW,MAAZ;GAAiB,aAAY;GAC3B,UAAA,oBAAC,WAAW,UAAZ,EAAA,UACE,oBAAC,MAAD,EAAM,MAAM,SAAS,OAAO,OAAO,IAAI,EAAI,CAAA,EACxB,CAAA;EACN,CAAA;CACJ,CAAA,EACL,CAAA;AAEhB;AAEA,WAAW,cAAc"}
@@ -13,21 +13,22 @@ var DevtoolsOverviewContainer = () => {
13
13
  clearSurfaceProfiler?.();
14
14
  Surface.clearMetrics();
15
15
  }, [clearSurfaceProfiler]);
16
+ const enrichedStats = useMemo(() => {
17
+ const byId = new Map(surfaceMetrics.map((metric) => [metric.id, metric]));
18
+ return surfaceProfilerStats.map((stat) => {
19
+ const metric = byId.get(stat.id);
20
+ return metric ? {
21
+ ...stat,
22
+ candidates: metric.candidates,
23
+ truncated: metric.truncated,
24
+ errors: metric.errors,
25
+ dataUnstable: metric.dataUnstable
26
+ } : stat;
27
+ });
28
+ }, [surfaceProfilerStats, surfaceMetrics]);
16
29
  return /* @__PURE__ */ jsx(StatsPanel, {
17
30
  stats,
18
- surfaceProfilerStats: useMemo(() => {
19
- const byId = new Map(surfaceMetrics.map((metric) => [metric.id, metric]));
20
- return surfaceProfilerStats.map((stat) => {
21
- const metric = byId.get(stat.id);
22
- return metric ? {
23
- ...stat,
24
- candidates: metric.candidates,
25
- truncated: metric.truncated,
26
- errors: metric.errors,
27
- dataUnstable: metric.dataUnstable
28
- } : stat;
29
- });
30
- }, [surfaceProfilerStats, surfaceMetrics]),
31
+ surfaceProfilerStats: enrichedStats,
31
32
  onRefresh: refreshStats,
32
33
  onClearSurfaceProfiler: handleClearSurfaceProfiler,
33
34
  children: /* @__PURE__ */ jsx(Surface.Surface, { type: AppSurface.DevtoolsOverview })
@@ -1 +1 @@
1
- {"version":3,"file":"chunk-DevtoolsOverviewContainer.mjs","names":[],"sources":["../../src/containers/DevtoolsOverviewContainer/DevtoolsOverviewContainer.tsx"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport React, { useCallback, useMemo } from 'react';\n\nimport { Surface } from '@dxos/app-framework/ui';\nimport { AppSurface } from '@dxos/app-toolkit/ui';\nimport { StatsPanel, useStats } from '@dxos/devtools';\n\nexport const DevtoolsOverviewContainer = () => {\n const [stats, refreshStats] = useStats();\n const surfaceProfilerStats = Surface.useProfilerStats();\n const surfaceMetrics = Surface.useMetrics();\n const clearSurfaceProfiler = Surface.useProfilerClear();\n\n // The panel joins profiler stats with dispatch metrics, so reset must clear both.\n const handleClearSurfaceProfiler = useCallback(() => {\n clearSurfaceProfiler?.();\n Surface.clearMetrics();\n }, [clearSurfaceProfiler]);\n\n // Join dispatch metrics onto the render-timing stats (both keyed by `surface/<id>/<role>`).\n const enrichedStats = useMemo(() => {\n const byId = new Map(surfaceMetrics.map((metric) => [metric.id, metric]));\n return surfaceProfilerStats.map((stat) => {\n const metric = byId.get(stat.id);\n return metric\n ? {\n ...stat,\n candidates: metric.candidates,\n truncated: metric.truncated,\n errors: metric.errors,\n dataUnstable: metric.dataUnstable,\n }\n : stat;\n });\n }, [surfaceProfilerStats, surfaceMetrics]);\n\n return (\n <StatsPanel\n stats={stats}\n surfaceProfilerStats={enrichedStats}\n onRefresh={refreshStats}\n onClearSurfaceProfiler={handleClearSurfaceProfiler}\n >\n <Surface.Surface type={AppSurface.DevtoolsOverview} />\n </StatsPanel>\n );\n};\n\nDevtoolsOverviewContainer.displayName = 'DevtoolsOverviewContainer';\n"],"mappings":";;;;;;AAUA,IAAa,kCAAkC;CAC7C,MAAM,CAAC,OAAO,gBAAgB,SAAS;CACvC,MAAM,uBAAuB,QAAQ,iBAAiB;CACtD,MAAM,iBAAiB,QAAQ,WAAW;CAC1C,MAAM,uBAAuB,QAAQ,iBAAiB;CAGtD,MAAM,6BAA6B,kBAAkB;EACnD,uBAAuB;EACvB,QAAQ,aAAa;CACvB,GAAG,CAAC,oBAAoB,CAAC;CAmBzB,OACE,oBAAC,YAAD;EACS;EACP,sBAnBkB,cAAc;GAClC,MAAM,OAAO,IAAI,IAAI,eAAe,KAAK,WAAW,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC;GACxE,OAAO,qBAAqB,KAAK,SAAS;IACxC,MAAM,SAAS,KAAK,IAAI,KAAK,EAAE;IAC/B,OAAO,SACH;KACE,GAAG;KACH,YAAY,OAAO;KACnB,WAAW,OAAO;KAClB,QAAQ,OAAO;KACf,cAAc,OAAO;IACvB,IACA;GACN,CAAC;EACH,GAAG,CAAC,sBAAsB,cAAc,CAKd;EACtB,WAAW;EACX,wBAAwB;YAExB,oBAAC,QAAQ,SAAT,EAAiB,MAAM,WAAW,iBAAmB,CAAA;CAC3C,CAAA;AAEhB;AAEA,0BAA0B,cAAc"}
1
+ {"version":3,"file":"chunk-DevtoolsOverviewContainer.mjs","names":[],"sources":["../../src/containers/DevtoolsOverviewContainer/DevtoolsOverviewContainer.tsx"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport React, { useCallback, useMemo } from 'react';\n\nimport { Surface } from '@dxos/app-framework/ui';\nimport { AppSurface } from '@dxos/app-toolkit/ui';\nimport { StatsPanel, useStats } from '@dxos/devtools';\n\nexport const DevtoolsOverviewContainer = () => {\n const [stats, refreshStats] = useStats();\n const surfaceProfilerStats = Surface.useProfilerStats();\n const surfaceMetrics = Surface.useMetrics();\n const clearSurfaceProfiler = Surface.useProfilerClear();\n\n // The panel joins profiler stats with dispatch metrics, so reset must clear both.\n const handleClearSurfaceProfiler = useCallback(() => {\n clearSurfaceProfiler?.();\n Surface.clearMetrics();\n }, [clearSurfaceProfiler]);\n\n // Join dispatch metrics onto the render-timing stats (both keyed by `surface/<id>/<role>`).\n const enrichedStats = useMemo(() => {\n const byId = new Map(surfaceMetrics.map((metric) => [metric.id, metric]));\n return surfaceProfilerStats.map((stat) => {\n const metric = byId.get(stat.id);\n return metric\n ? {\n ...stat,\n candidates: metric.candidates,\n truncated: metric.truncated,\n errors: metric.errors,\n dataUnstable: metric.dataUnstable,\n }\n : stat;\n });\n }, [surfaceProfilerStats, surfaceMetrics]);\n\n return (\n <StatsPanel\n stats={stats}\n surfaceProfilerStats={enrichedStats}\n onRefresh={refreshStats}\n onClearSurfaceProfiler={handleClearSurfaceProfiler}\n >\n <Surface.Surface type={AppSurface.DevtoolsOverview} />\n </StatsPanel>\n );\n};\n\nDevtoolsOverviewContainer.displayName = 'DevtoolsOverviewContainer';\n"],"mappings":";;;;;;AAUA,IAAa,kCAAkC;CAC7C,MAAM,CAAC,OAAO,gBAAgB,SAAS;CACvC,MAAM,uBAAuB,QAAQ,iBAAiB;CACtD,MAAM,iBAAiB,QAAQ,WAAW;CAC1C,MAAM,uBAAuB,QAAQ,iBAAiB;CAGtD,MAAM,6BAA6B,kBAAkB;EACnD,uBAAuB;EACvB,QAAQ,aAAa;CACvB,GAAG,CAAC,oBAAoB,CAAC;CAGzB,MAAM,gBAAgB,cAAc;EAClC,MAAM,OAAO,IAAI,IAAI,eAAe,KAAK,WAAW,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC;EACxE,OAAO,qBAAqB,KAAK,SAAS;GACxC,MAAM,SAAS,KAAK,IAAI,KAAK,EAAE;GAC/B,OAAO,SACH;IACE,GAAG;IACH,YAAY,OAAO;IACnB,WAAW,OAAO;IAClB,QAAQ,OAAO;IACf,cAAc,OAAO;GACvB,IACA;EACN,CAAC;CACH,GAAG,CAAC,sBAAsB,cAAc,CAAC;CAEzC,OACE,oBAAC,YAAD;EACS;EACP,sBAAsB;EACtB,WAAW;EACX,wBAAwB;EAExB,UAAA,oBAAC,QAAQ,SAAT,EAAiB,MAAM,WAAW,iBAAmB,CAAA;CAC3C,CAAA;AAEhB;AAEA,0BAA0B,cAAc"}