@dxos/plugin-observability 0.8.4-main.21d9917 → 0.8.4-main.2244d791bb

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 (113) hide show
  1. package/dist/lib/browser/{app-graph-builder-6KDHLPUO.mjs → app-graph-builder-7PBOGFFG.mjs} +4 -3
  2. package/dist/lib/browser/app-graph-builder-7PBOGFFG.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-PYNLPSSZ.mjs → chunk-T3EKFAAB.mjs} +9 -4
  4. package/dist/lib/browser/chunk-T3EKFAAB.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-SN7DIHQG.mjs → chunk-UTYAG5Z3.mjs} +35 -14
  6. package/dist/lib/browser/chunk-UTYAG5Z3.mjs.map +7 -0
  7. package/dist/lib/browser/cli/index.mjs +5 -4
  8. package/dist/lib/browser/cli/index.mjs.map +3 -3
  9. package/dist/lib/browser/{client-ready-YWKHC5S2.mjs → client-ready-ZVLSHDH6.mjs} +18 -22
  10. package/dist/lib/browser/client-ready-ZVLSHDH6.mjs.map +7 -0
  11. package/dist/lib/browser/index.mjs +24 -23
  12. package/dist/lib/browser/index.mjs.map +3 -3
  13. package/dist/lib/browser/meta.json +1 -1
  14. package/dist/lib/browser/{operation-resolver-4ROZET3B.mjs → operation-resolver-GJYJZPY3.mjs} +21 -24
  15. package/dist/lib/browser/operation-resolver-GJYJZPY3.mjs.map +7 -0
  16. package/dist/lib/browser/{react-surface-SJTESQAF.mjs → react-surface-4RABGTCC.mjs} +10 -9
  17. package/dist/lib/browser/react-surface-4RABGTCC.mjs.map +7 -0
  18. package/dist/lib/browser/{settings-SQ4ICR7F.mjs → settings-QQBXDLBH.mjs} +6 -5
  19. package/dist/lib/browser/settings-QQBXDLBH.mjs.map +7 -0
  20. package/dist/lib/browser/{state-IKCFXHYV.mjs → state-SSUNAB2P.mjs} +6 -6
  21. package/dist/lib/browser/state-SSUNAB2P.mjs.map +7 -0
  22. package/dist/lib/browser/types/index.mjs +1 -1
  23. package/dist/lib/node-esm/{app-graph-builder-4YHKY4SP.mjs → app-graph-builder-D77CGMCQ.mjs} +4 -3
  24. package/dist/lib/node-esm/app-graph-builder-D77CGMCQ.mjs.map +7 -0
  25. package/dist/lib/node-esm/{chunk-HNMV7ZZZ.mjs → chunk-PE6CKAA6.mjs} +35 -14
  26. package/dist/lib/node-esm/chunk-PE6CKAA6.mjs.map +7 -0
  27. package/dist/lib/node-esm/{chunk-4T4N2NJZ.mjs → chunk-VC5HVE77.mjs} +9 -4
  28. package/dist/lib/node-esm/chunk-VC5HVE77.mjs.map +7 -0
  29. package/dist/lib/node-esm/cli/index.mjs +5 -4
  30. package/dist/lib/node-esm/cli/index.mjs.map +3 -3
  31. package/dist/lib/node-esm/{client-ready-YLYG6F6H.mjs → client-ready-JXG727PH.mjs} +18 -22
  32. package/dist/lib/node-esm/client-ready-JXG727PH.mjs.map +7 -0
  33. package/dist/lib/node-esm/index.mjs +24 -23
  34. package/dist/lib/node-esm/index.mjs.map +3 -3
  35. package/dist/lib/node-esm/meta.json +1 -1
  36. package/dist/lib/node-esm/{operation-resolver-UI7ZINXR.mjs → operation-resolver-NB7XDO3M.mjs} +21 -24
  37. package/dist/lib/node-esm/operation-resolver-NB7XDO3M.mjs.map +7 -0
  38. package/dist/lib/node-esm/{react-surface-D53VLGHY.mjs → react-surface-ZHTRUHHM.mjs} +10 -9
  39. package/dist/lib/node-esm/react-surface-ZHTRUHHM.mjs.map +7 -0
  40. package/dist/lib/node-esm/{settings-WIRCHLWE.mjs → settings-IZ2DBP4E.mjs} +6 -5
  41. package/dist/lib/node-esm/settings-IZ2DBP4E.mjs.map +7 -0
  42. package/dist/lib/node-esm/{state-MQR4PNOT.mjs → state-3HUC5SJV.mjs} +6 -6
  43. package/dist/lib/node-esm/state-3HUC5SJV.mjs.map +7 -0
  44. package/dist/lib/node-esm/types/index.mjs +1 -1
  45. package/dist/types/src/ObservabilityPlugin.d.ts +1 -1
  46. package/dist/types/src/ObservabilityPlugin.d.ts.map +1 -1
  47. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +1 -1
  48. package/dist/types/src/capabilities/client-ready/client-ready.d.ts +3 -3
  49. package/dist/types/src/capabilities/client-ready/client-ready.d.ts.map +1 -1
  50. package/dist/types/src/capabilities/client-ready/index.d.ts +2 -4
  51. package/dist/types/src/capabilities/client-ready/index.d.ts.map +1 -1
  52. package/dist/types/src/capabilities/operation-resolver/index.d.ts +1 -1
  53. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +1 -1
  54. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +2 -2
  55. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +1 -1
  56. package/dist/types/src/capabilities/react-surface/index.d.ts +1 -1
  57. package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -1
  58. package/dist/types/src/capabilities/react-surface/react-surface.d.ts +2 -2
  59. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -1
  60. package/dist/types/src/capabilities/settings/index.d.ts +1 -1
  61. package/dist/types/src/capabilities/settings/index.d.ts.map +1 -1
  62. package/dist/types/src/capabilities/settings/settings.d.ts +3 -2
  63. package/dist/types/src/capabilities/settings/settings.d.ts.map +1 -1
  64. package/dist/types/src/capabilities/state/state.d.ts.map +1 -1
  65. package/dist/types/src/cli/plugin.d.ts.map +1 -1
  66. package/dist/types/src/components/FeedbackForm.d.ts +3 -3
  67. package/dist/types/src/components/FeedbackForm.d.ts.map +1 -1
  68. package/dist/types/src/components/FeedbackForm.stories.d.ts +2 -1
  69. package/dist/types/src/components/FeedbackForm.stories.d.ts.map +1 -1
  70. package/dist/types/src/components/HelpContainer.d.ts +1 -0
  71. package/dist/types/src/components/HelpContainer.d.ts.map +1 -1
  72. package/dist/types/src/translations.d.ts +1 -0
  73. package/dist/types/src/translations.d.ts.map +1 -1
  74. package/dist/types/src/types/capabilities.d.ts +1 -1
  75. package/dist/types/src/types/capabilities.d.ts.map +1 -1
  76. package/dist/types/src/types/events.d.ts.map +1 -1
  77. package/dist/types/src/types/schema.d.ts +2 -0
  78. package/dist/types/src/types/schema.d.ts.map +1 -1
  79. package/dist/types/tsconfig.tsbuildinfo +1 -1
  80. package/package.json +31 -29
  81. package/src/ObservabilityPlugin.ts +11 -10
  82. package/src/capabilities/app-graph-builder/app-graph-builder.ts +3 -2
  83. package/src/capabilities/client-ready/client-ready.ts +17 -29
  84. package/src/capabilities/client-ready/index.ts +3 -1
  85. package/src/capabilities/operation-resolver/operation-resolver.ts +19 -24
  86. package/src/capabilities/react-surface/react-surface.tsx +8 -7
  87. package/src/capabilities/settings/settings.ts +3 -2
  88. package/src/capabilities/state/state.ts +4 -4
  89. package/src/cli/plugin.ts +4 -3
  90. package/src/components/FeedbackForm.stories.tsx +1 -1
  91. package/src/components/FeedbackForm.tsx +10 -5
  92. package/src/components/HelpContainer.tsx +27 -7
  93. package/src/components/ObservabilitySettings.tsx +10 -10
  94. package/src/translations.ts +1 -0
  95. package/src/types/capabilities.ts +1 -1
  96. package/src/types/events.ts +3 -2
  97. package/src/types/schema.ts +6 -0
  98. package/dist/lib/browser/app-graph-builder-6KDHLPUO.mjs.map +0 -7
  99. package/dist/lib/browser/chunk-PYNLPSSZ.mjs.map +0 -7
  100. package/dist/lib/browser/chunk-SN7DIHQG.mjs.map +0 -7
  101. package/dist/lib/browser/client-ready-YWKHC5S2.mjs.map +0 -7
  102. package/dist/lib/browser/operation-resolver-4ROZET3B.mjs.map +0 -7
  103. package/dist/lib/browser/react-surface-SJTESQAF.mjs.map +0 -7
  104. package/dist/lib/browser/settings-SQ4ICR7F.mjs.map +0 -7
  105. package/dist/lib/browser/state-IKCFXHYV.mjs.map +0 -7
  106. package/dist/lib/node-esm/app-graph-builder-4YHKY4SP.mjs.map +0 -7
  107. package/dist/lib/node-esm/chunk-4T4N2NJZ.mjs.map +0 -7
  108. package/dist/lib/node-esm/chunk-HNMV7ZZZ.mjs.map +0 -7
  109. package/dist/lib/node-esm/client-ready-YLYG6F6H.mjs.map +0 -7
  110. package/dist/lib/node-esm/operation-resolver-UI7ZINXR.mjs.map +0 -7
  111. package/dist/lib/node-esm/react-surface-D53VLGHY.mjs.map +0 -7
  112. package/dist/lib/node-esm/settings-WIRCHLWE.mjs.map +0 -7
  113. package/dist/lib/node-esm/state-MQR4PNOT.mjs.map +0 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-observability",
3
- "version": "0.8.4-main.21d9917",
3
+ "version": "0.8.4-main.2244d791bb",
4
4
  "description": "DXOS app framework plugin for hooking up app observability",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -45,44 +45,46 @@
45
45
  "src"
46
46
  ],
47
47
  "dependencies": {
48
- "@effect-atom/atom": "^0.4.13",
49
- "@effect-atom/atom-react": "^0.4.6",
50
- "effect": "3.19.11",
48
+ "@effect-atom/atom": "^0.5.1",
49
+ "@effect-atom/atom-react": "^0.5.0",
50
+ "effect": "3.19.16",
51
51
  "localforage": "^1.10.0",
52
- "@dxos/app-framework": "0.8.4-main.21d9917",
53
- "@dxos/async": "0.8.4-main.21d9917",
54
- "@dxos/context": "0.8.4-main.21d9917",
55
- "@dxos/echo": "0.8.4-main.21d9917",
56
- "@dxos/effect": "0.8.4-main.21d9917",
57
- "@dxos/invariant": "0.8.4-main.21d9917",
58
- "@dxos/observability": "0.8.4-main.21d9917",
59
- "@dxos/log": "0.8.4-main.21d9917",
60
- "@dxos/operation": "0.8.4-main.21d9917",
61
- "@dxos/plugin-graph": "0.8.4-main.21d9917",
62
- "@dxos/protocols": "0.8.4-main.21d9917",
63
- "@dxos/react-ui-form": "0.8.4-main.21d9917",
64
- "@dxos/react-ui-stack": "0.8.4-main.21d9917",
65
- "@dxos/util": "0.8.4-main.21d9917",
66
- "@dxos/react-client": "0.8.4-main.21d9917"
52
+ "@dxos/app-framework": "0.8.4-main.2244d791bb",
53
+ "@dxos/app-toolkit": "0.8.4-main.2244d791bb",
54
+ "@dxos/async": "0.8.4-main.2244d791bb",
55
+ "@dxos/context": "0.8.4-main.2244d791bb",
56
+ "@dxos/invariant": "0.8.4-main.2244d791bb",
57
+ "@dxos/echo": "0.8.4-main.2244d791bb",
58
+ "@dxos/effect": "0.8.4-main.2244d791bb",
59
+ "@dxos/log": "0.8.4-main.2244d791bb",
60
+ "@dxos/operation": "0.8.4-main.2244d791bb",
61
+ "@dxos/observability": "0.8.4-main.2244d791bb",
62
+ "@dxos/plugin-graph": "0.8.4-main.2244d791bb",
63
+ "@dxos/protocols": "0.8.4-main.2244d791bb",
64
+ "@dxos/react-client": "0.8.4-main.2244d791bb",
65
+ "@dxos/react-hooks": "0.8.4-main.2244d791bb",
66
+ "@dxos/react-ui-form": "0.8.4-main.2244d791bb",
67
+ "@dxos/react-ui-stack": "0.8.4-main.2244d791bb",
68
+ "@dxos/util": "0.8.4-main.2244d791bb"
67
69
  },
68
70
  "devDependencies": {
69
- "@effect-atom/atom-react": "^0.4.6",
70
- "@effect/platform": "0.93.6",
71
+ "@effect-atom/atom-react": "^0.5.0",
72
+ "@effect/platform": "0.94.4",
71
73
  "@types/react": "~19.2.7",
72
74
  "react": "~19.2.3",
73
75
  "vite": "7.1.9",
74
- "@dxos/react-ui": "0.8.4-main.21d9917",
75
- "@dxos/ui-theme": "0.8.4-main.21d9917",
76
- "@dxos/storybook-utils": "0.8.4-main.21d9917"
76
+ "@dxos/react-ui": "0.8.4-main.2244d791bb",
77
+ "@dxos/storybook-utils": "0.8.4-main.2244d791bb",
78
+ "@dxos/ui-theme": "0.8.4-main.2244d791bb"
77
79
  },
78
80
  "peerDependencies": {
79
- "@effect-atom/atom-react": "^0.4.6",
80
- "@effect/platform": "0.93.6",
81
- "effect": "3.19.11",
81
+ "@effect-atom/atom-react": "^0.5.0",
82
+ "@effect/platform": "0.94.4",
83
+ "effect": "3.19.16",
82
84
  "react": "~19.2.3",
83
85
  "react-dom": "~19.2.3",
84
- "@dxos/react-ui": "0.8.4-main.21d9917",
85
- "@dxos/ui-theme": "0.8.4-main.21d9917"
86
+ "@dxos/react-ui": "0.8.4-main.2244d791bb",
87
+ "@dxos/ui-theme": "0.8.4-main.2244d791bb"
86
88
  },
87
89
  "publishConfig": {
88
90
  "access": "public"
@@ -4,7 +4,8 @@
4
4
 
5
5
  import * as Effect from 'effect/Effect';
6
6
 
7
- import { ActivationEvent, Capability, Common, Plugin } from '@dxos/app-framework';
7
+ import { ActivationEvent, ActivationEvents, Capability, Plugin } from '@dxos/app-framework';
8
+ import { AppActivationEvents, AppPlugin } from '@dxos/app-toolkit';
8
9
  import { type Observability } from '@dxos/observability';
9
10
 
10
11
  import {
@@ -22,13 +23,16 @@ import { ObservabilityCapabilities } from './types';
22
23
 
23
24
  export type ObservabilityPluginOptions = {
24
25
  namespace: string;
25
- observability: () => Promise<Observability>;
26
+ observability: () => Promise<Observability.Observability>;
26
27
  };
27
28
 
28
29
  export const ObservabilityPlugin = Plugin.define<ObservabilityPluginOptions>(meta).pipe(
30
+ AppPlugin.addAppGraphModule({ activate: AppGraphBuilder }),
31
+ AppPlugin.addSurfaceModule({ activate: ReactSurface }),
32
+ AppPlugin.addTranslationsModule({ translations }),
29
33
  Plugin.addModule(({ namespace, observability }) => ({
30
34
  id: 'observability',
31
- activatesOn: Common.ActivationEvent.Startup,
35
+ activatesOn: ActivationEvents.Startup,
32
36
  activate: () =>
33
37
  Effect.gen(function* () {
34
38
  const obs = yield* Effect.tryPromise(() => observability());
@@ -36,27 +40,24 @@ export const ObservabilityPlugin = Plugin.define<ObservabilityPluginOptions>(met
36
40
  }),
37
41
  })),
38
42
  Plugin.addModule({
39
- activatesOn: Common.ActivationEvent.SetupSettings,
43
+ activatesOn: AppActivationEvents.SetupSettings,
40
44
  activate: ObservabilitySettings,
41
45
  }),
42
46
  Plugin.addModule(({ namespace }) => ({
43
47
  id: Capability.getModuleTag(ObservabilityState),
44
- activatesOn: Common.ActivationEvent.Startup,
48
+ activatesOn: ActivationEvents.Startup,
45
49
  activatesAfter: [ObservabilityEvents.StateReady],
46
50
  activate: () => ObservabilityState({ namespace }),
47
51
  })),
48
- Common.Plugin.addTranslationsModule({ translations }),
49
52
  Plugin.addModule(({ namespace }) => ({
50
53
  id: Capability.getModuleTag(OperationResolver),
51
- activatesOn: Common.ActivationEvent.SetupOperationResolver,
54
+ activatesOn: ActivationEvents.SetupOperationResolver,
52
55
  activate: () => OperationResolver({ namespace }),
53
56
  })),
54
- Common.Plugin.addSurfaceModule({ activate: ReactSurface }),
55
- Common.Plugin.addAppGraphModule({ activate: AppGraphBuilder }),
56
57
  Plugin.addModule(({ namespace, observability }) => ({
57
58
  id: Capability.getModuleTag(ClientReady),
58
59
  activatesOn: ActivationEvent.allOf(
59
- Common.ActivationEvent.OperationInvokerReady,
60
+ ActivationEvents.OperationInvokerReady,
60
61
  ObservabilityEvents.StateReady,
61
62
  ClientReadyEvent,
62
63
  ),
@@ -4,7 +4,8 @@
4
4
 
5
5
  import * as Effect from 'effect/Effect';
6
6
 
7
- import { Capability, Common } from '@dxos/app-framework';
7
+ import { Capability } from '@dxos/app-framework';
8
+ import { AppCapabilities } from '@dxos/app-toolkit';
8
9
  import { GraphBuilder, NodeMatcher } from '@dxos/plugin-graph';
9
10
 
10
11
  import { meta } from '../../meta';
@@ -37,6 +38,6 @@ export default Capability.makeModule(
37
38
  }),
38
39
  ]);
39
40
 
40
- return Capability.contributes(Common.Capability.AppGraphBuilder, extensions);
41
+ return Capability.contributes(AppCapabilities.AppGraphBuilder, extensions);
41
42
  }),
42
43
  );
@@ -4,23 +4,24 @@
4
4
 
5
5
  import * as Effect from 'effect/Effect';
6
6
 
7
- import { Capability, Common, SettingsOperation } from '@dxos/app-framework';
8
- import { type Observability, setupTelemetryListeners } from '@dxos/observability';
7
+ import { Capabilities, Capability } from '@dxos/app-framework';
8
+ import { LayoutOperation, SettingsOperation } from '@dxos/app-toolkit';
9
+ import { type Observability, ObservabilityProvider } from '@dxos/observability';
9
10
 
10
11
  import { meta } from '../../meta';
11
12
  import { ClientCapability, ObservabilityCapabilities, ObservabilityOperation } from '../../types';
12
13
 
13
- type ClientReadyOptions = {
14
+ export type ClientReadyOptions = {
14
15
  namespace: string;
15
- observability: Observability;
16
+ observability: Observability.Observability;
16
17
  };
17
18
 
18
19
  export default Capability.makeModule(
19
20
  Effect.fnUntraced(function* (props?: ClientReadyOptions) {
20
- const { namespace, observability } = props!;
21
- const manager = yield* Capability.get(Common.Capability.PluginManager);
22
- const { invokePromise } = yield* Capability.get(Common.Capability.OperationInvoker);
23
- const registry = yield* Capability.get(Common.Capability.AtomRegistry);
21
+ const { observability } = props!;
22
+ const manager = yield* Capability.get(Capabilities.PluginManager);
23
+ const { invokePromise } = yield* Capability.get(Capabilities.OperationInvoker);
24
+ const registry = yield* Capability.get(Capabilities.AtomRegistry);
24
25
  const stateAtom = yield* Capability.get(ObservabilityCapabilities.State);
25
26
  const client = yield* Capability.get(ClientCapability);
26
27
 
@@ -30,7 +31,7 @@ export default Capability.makeModule(
30
31
  environment && environment !== 'ci' && !environment.endsWith('.local') && !environment.endsWith('.lan');
31
32
  const state = registry.get(stateAtom);
32
33
  if (!state.notified && notify) {
33
- await invokePromise(Common.LayoutOperation.AddToast, {
34
+ await invokePromise(LayoutOperation.AddToast, {
34
35
  id: `${meta.id}/notice`,
35
36
  title: ['observability toast label', { ns: meta.id }],
36
37
  description: ['observability toast description', { ns: meta.id }],
@@ -49,7 +50,7 @@ export default Capability.makeModule(
49
50
  // Ensure errors are tagged with enabled plugins to help with reproductions.
50
51
  const enabledPlugins = manager.getEnabled();
51
52
  for (const plugin of enabledPlugins) {
52
- observability?.setTag(`pluginEnabled-${plugin}`, 'true', 'errors');
53
+ observability.setTags({ [`pluginEnabled-${plugin}`]: 'true' }, 'errors');
53
54
  }
54
55
 
55
56
  yield* Effect.tryPromise(() =>
@@ -62,18 +63,11 @@ export default Capability.makeModule(
62
63
  }),
63
64
  );
64
65
 
65
- // Start client observability (i.e. not running as shared worker)
66
- // TODO(nf): how to prevent multiple instances for single shared worker?
67
- const cleanup = setupTelemetryListeners(namespace, client, observability);
68
-
69
- yield* Effect.tryPromise(() =>
70
- Promise.all([
71
- observability.setIdentityTags(client.services.services),
72
- observability.startRuntimeMetrics(client),
73
- observability.startNetworkMetrics(client.services.services),
74
- observability.startSpacesMetrics(client, namespace),
75
- ]),
76
- );
66
+ // Add client data providers.
67
+ yield* observability.addDataProvider(ObservabilityProvider.Client.identityProvider(client.services.services));
68
+ yield* observability.addDataProvider(ObservabilityProvider.Client.networkMetricsProvider(client.services.services));
69
+ yield* observability.addDataProvider(ObservabilityProvider.Client.runtimeMetricsProvider(client.services.services));
70
+ yield* observability.addDataProvider(ObservabilityProvider.Client.spacesMetricsProvider(client));
77
71
 
78
72
  if (client.halo.identity.get()) {
79
73
  yield* Effect.tryPromise(() => sendPrivacyNotice());
@@ -81,17 +75,11 @@ export default Capability.makeModule(
81
75
  const subscription = client.halo.identity.subscribe(async (identity) => {
82
76
  if (identity && observability) {
83
77
  await sendPrivacyNotice();
84
- await observability.setIdentityTags(client.services.services);
85
78
  subscription.unsubscribe();
86
79
  }
87
80
  });
88
81
  }
89
82
 
90
- return Capability.contributes(ObservabilityCapabilities.Observability, observability, () =>
91
- Effect.tryPromise(async () => {
92
- cleanup();
93
- await observability.close();
94
- }),
95
- );
83
+ return Capability.contributes(ObservabilityCapabilities.Observability, observability, () => observability.close());
96
84
  }),
97
85
  );
@@ -4,4 +4,6 @@
4
4
 
5
5
  import { Capability } from '@dxos/app-framework';
6
6
 
7
- export const ClientReady = Capability.lazy('ClientReady', () => import('./client-ready'));
7
+ import { type ClientReadyOptions } from './client-ready';
8
+
9
+ export const ClientReady = Capability.lazy<ClientReadyOptions>('ClientReady', () => import('./client-ready'));
@@ -4,46 +4,47 @@
4
4
 
5
5
  import * as Effect from 'effect/Effect';
6
6
 
7
- import { Capability, Common } from '@dxos/app-framework';
8
- import { getTelemetryIdentity, storeObservabilityDisabled } from '@dxos/observability';
7
+ import { Capabilities, Capability } from '@dxos/app-framework';
8
+ import { AppCapabilities } from '@dxos/app-toolkit';
9
+ import { Observability } from '@dxos/observability';
9
10
  import { OperationResolver } from '@dxos/operation';
10
11
 
11
12
  import { type ObservabilitySettingsProps } from '../../components';
12
13
  import { meta } from '../../meta';
13
- import { ClientCapability, ObservabilityCapabilities, ObservabilityOperation } from '../../types';
14
+ import { ObservabilityCapabilities, ObservabilityOperation } from '../../types';
14
15
 
15
16
  export default Capability.makeModule(
16
17
  Effect.fnUntraced(function* (props?: { namespace: string }) {
17
18
  const { namespace } = props!;
18
19
  const capabilities = yield* Capability.Service;
19
20
 
20
- return Capability.contributes(Common.Capability.OperationResolver, [
21
+ return Capability.contributes(Capabilities.OperationResolver, [
21
22
  //
22
23
  // Toggle
23
24
  //
24
25
  OperationResolver.make({
25
26
  operation: ObservabilityOperation.Toggle,
26
27
  handler: Effect.fnUntraced(function* (input) {
27
- const client = yield* Capability.get(ClientCapability);
28
28
  const observability = yield* Capability.get(ObservabilityCapabilities.Observability);
29
- const registry = capabilities.get(Common.Capability.AtomRegistry);
30
- const allSettings = capabilities.getAll(Common.Capability.Settings);
31
- const settingsObj = allSettings.find((s: Common.Capability.Settings) => s.prefix === meta.id);
29
+ const registry = capabilities.get(Capabilities.AtomRegistry);
30
+ const allSettings = capabilities.getAll(AppCapabilities.Settings);
31
+ const settingsObj = allSettings.find((s: AppCapabilities.Settings) => s.prefix === meta.id);
32
32
  if (!settingsObj) {
33
33
  return false;
34
34
  }
35
35
  const settings = registry.get(settingsObj.atom) as ObservabilitySettingsProps;
36
36
  const newEnabled = input.state ?? !settings.enabled;
37
37
  registry.set(settingsObj.atom, { ...settings, enabled: newEnabled });
38
- observability.track({
39
- ...getTelemetryIdentity(client),
40
- action: 'observability.toggle',
41
- properties: {
42
- enabled: newEnabled,
43
- },
38
+ observability.events.captureEvent('observability.toggle', {
39
+ enabled: newEnabled,
44
40
  });
45
- observability.setMode(newEnabled ? 'basic' : 'disabled');
46
- yield* Effect.promise(() => storeObservabilityDisabled(namespace, !newEnabled));
41
+
42
+ if (newEnabled) {
43
+ yield* observability.enable();
44
+ } else {
45
+ yield* observability.disable();
46
+ }
47
+ yield* Effect.promise(() => Observability.storeObservabilityDisabled(namespace, !newEnabled));
47
48
  return newEnabled;
48
49
  }),
49
50
  }),
@@ -56,14 +57,8 @@ export default Capability.makeModule(
56
57
  handler: Effect.fnUntraced(function* (input) {
57
58
  // NOTE: This is to ensure that events fired before observability is ready are still sent.
58
59
  const observability = yield* Capability.waitFor(ObservabilityCapabilities.Observability);
59
- const client = yield* Capability.get(ClientCapability);
60
60
  const properties = input.properties ?? {};
61
-
62
- observability.track({
63
- ...getTelemetryIdentity(client),
64
- action: input.name,
65
- properties,
66
- });
61
+ observability.events.captureEvent(input.name, properties);
67
62
  }),
68
63
  }),
69
64
 
@@ -74,7 +69,7 @@ export default Capability.makeModule(
74
69
  operation: ObservabilityOperation.CaptureUserFeedback,
75
70
  handler: Effect.fnUntraced(function* (input) {
76
71
  const observability = yield* Capability.get(ObservabilityCapabilities.Observability);
77
- observability.captureUserFeedback(input.message);
72
+ observability.feedback.captureUserFeedback({ message: input.message, includeLogs: input.includeLogs });
78
73
  }),
79
74
  }),
80
75
  ]);
@@ -5,26 +5,27 @@
5
5
  import * as Effect from 'effect/Effect';
6
6
  import React from 'react';
7
7
 
8
- import { Capability, Common } from '@dxos/app-framework';
9
- import { useSettingsState } from '@dxos/app-framework/react';
8
+ import { Capabilities, Capability } from '@dxos/app-framework';
9
+ import { Surface, useSettingsState } from '@dxos/app-framework/ui';
10
+ import { AppCapabilities } from '@dxos/app-toolkit';
10
11
 
11
12
  import { HelpContainer, ObservabilitySettings, type ObservabilitySettingsProps } from '../../components';
12
13
  import { meta } from '../../meta';
13
14
 
14
15
  export default Capability.makeModule(() =>
15
16
  Effect.succeed(
16
- Capability.contributes(Common.Capability.ReactSurface, [
17
- Common.createSurface({
17
+ Capability.contributes(Capabilities.ReactSurface, [
18
+ Surface.create({
18
19
  id: meta.id,
19
20
  role: 'article',
20
- filter: (data): data is { subject: Common.Capability.Settings } =>
21
- Common.Capability.isSettings(data.subject) && data.subject.prefix === meta.id,
21
+ filter: (data): data is { subject: AppCapabilities.Settings } =>
22
+ AppCapabilities.isSettings(data.subject) && data.subject.prefix === meta.id,
22
23
  component: ({ data: { subject } }) => {
23
24
  const { settings, updateSettings } = useSettingsState<ObservabilitySettingsProps>(subject.atom);
24
25
  return <ObservabilitySettings settings={settings} onSettingsChange={updateSettings} />;
25
26
  },
26
27
  }),
27
- Common.createSurface({
28
+ Surface.create({
28
29
  id: `${meta.id}/help`,
29
30
  role: 'deck-companion--help',
30
31
  component: () => <HelpContainer />,
@@ -4,7 +4,8 @@
4
4
 
5
5
  import * as Effect from 'effect/Effect';
6
6
 
7
- import { Capability, Common } from '@dxos/app-framework';
7
+ import { Capability } from '@dxos/app-framework';
8
+ import { AppCapabilities } from '@dxos/app-toolkit';
8
9
  import { createKvsStore } from '@dxos/effect';
9
10
 
10
11
  import { ObservabilitySettingsSchema } from '../../components';
@@ -23,7 +24,7 @@ export default Capability.makeModule(() =>
23
24
 
24
25
  return [
25
26
  Capability.contributes(ObservabilityCapabilities.Settings, settingsAtom),
26
- Capability.contributes(Common.Capability.Settings, {
27
+ Capability.contributes(AppCapabilities.Settings, {
27
28
  prefix: meta.id,
28
29
  schema: ObservabilitySettingsSchema,
29
30
  atom: settingsAtom,
@@ -4,9 +4,9 @@
4
4
 
5
5
  import * as Effect from 'effect/Effect';
6
6
 
7
- import { Capability, Common } from '@dxos/app-framework';
7
+ import { Capabilities, Capability } from '@dxos/app-framework';
8
8
  import { createKvsStore } from '@dxos/effect';
9
- import { getObservabilityGroup } from '@dxos/observability';
9
+ import { Observability } from '@dxos/observability';
10
10
 
11
11
  import { meta } from '../../meta';
12
12
  import { ObservabilityCapabilities } from '../../types';
@@ -21,8 +21,8 @@ export default Capability.makeModule(
21
21
  });
22
22
 
23
23
  // NOTE: Group is set at runtime, not persisted.
24
- const group = yield* Effect.tryPromise(() => getObservabilityGroup(namespace));
25
- const registry = yield* Capability.get(Common.Capability.AtomRegistry);
24
+ const group = yield* Effect.tryPromise(() => Observability.getObservabilityGroup(namespace));
25
+ const registry = yield* Capability.get(Capabilities.AtomRegistry);
26
26
  registry.set(stateAtom, { ...registry.get(stateAtom), group });
27
27
 
28
28
  return Capability.contributes(ObservabilityCapabilities.State, stateAtom);
package/src/cli/plugin.ts CHANGED
@@ -4,7 +4,8 @@
4
4
 
5
5
  import * as Effect from 'effect/Effect';
6
6
 
7
- import { Capability, Common, Plugin } from '@dxos/app-framework';
7
+ import { Capabilities, Capability, Plugin } from '@dxos/app-framework';
8
+ import { AppPlugin } from '@dxos/app-toolkit';
8
9
  import { OperationResolver } from '@dxos/operation';
9
10
 
10
11
  import { meta } from '../meta';
@@ -12,10 +13,10 @@ import { ObservabilityOperation } from '../types';
12
13
 
13
14
  // TODO(wittjosiah): Hook up.
14
15
  export const ObservabilityPlugin = Plugin.define(meta).pipe(
15
- Common.Plugin.addOperationResolverModule({
16
+ AppPlugin.addOperationResolverModule({
16
17
  activate: () =>
17
18
  Effect.succeed(
18
- Capability.contributes(Common.Capability.OperationResolver, [
19
+ Capability.contributes(Capabilities.OperationResolver, [
19
20
  OperationResolver.make({
20
21
  operation: ObservabilityOperation.SendEvent,
21
22
  handler: () => Effect.void,
@@ -13,7 +13,7 @@ import { FeedbackForm } from './FeedbackForm';
13
13
  const meta = {
14
14
  title: 'plugins/plugin-observability/FeedbackForm',
15
15
  component: FeedbackForm,
16
- decorators: [withTheme, withLayout({ layout: 'column' })],
16
+ decorators: [withTheme(), withLayout({ layout: 'column' })],
17
17
  parameters: {
18
18
  layout: 'fullscreen',
19
19
  translations,
@@ -5,21 +5,26 @@
5
5
  import React from 'react';
6
6
 
7
7
  import { useTranslation } from '@dxos/react-ui';
8
- import { Form, type FormRootProps } from '@dxos/react-ui-form';
8
+ import { Form, type FormRootProps, type FormSubmitProps } from '@dxos/react-ui-form';
9
9
 
10
10
  import { meta } from '../meta';
11
11
  import { UserFeedback } from '../types';
12
12
 
13
- export type FeedbackFormProps = Pick<FormRootProps<UserFeedback>, 'onSave'>;
13
+ export type FeedbackFormProps = Pick<FormRootProps<UserFeedback>, 'onSave'> & Pick<FormSubmitProps, 'disabled'>;
14
14
 
15
- export const FeedbackForm = ({ onSave }: FeedbackFormProps) => {
15
+ const defaultValues: UserFeedback = {
16
+ message: '',
17
+ includeLogs: true,
18
+ };
19
+
20
+ export const FeedbackForm = ({ onSave, disabled }: FeedbackFormProps) => {
16
21
  const { t } = useTranslation(meta.id);
17
22
 
18
23
  return (
19
- <Form.Root schema={UserFeedback} onSave={onSave}>
24
+ <Form.Root schema={UserFeedback} defaultValues={defaultValues} onSave={onSave}>
20
25
  <Form.Content>
21
26
  <Form.FieldSet />
22
- <Form.Submit icon='ph--paper-plane-tilt--regular' label={t('send feedback label')} />
27
+ <Form.Submit icon='ph--paper-plane-tilt--regular' label={t('send feedback label')} disabled={disabled} />
23
28
  </Form.Content>
24
29
  </Form.Root>
25
30
  );
@@ -2,25 +2,45 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import React, { useCallback } from 'react';
5
+ import * as Effect from 'effect/Effect';
6
+ import React, { useCallback, useState } from 'react';
6
7
 
7
- import { Common } from '@dxos/app-framework';
8
- import { useOperationInvoker } from '@dxos/app-framework/react';
8
+ import { useCapability, useOperationInvoker } from '@dxos/app-framework/ui';
9
+ import { LayoutOperation } from '@dxos/app-toolkit';
10
+ import { runAndForwardErrors } from '@dxos/effect';
11
+ import { useAsyncEffect } from '@dxos/react-hooks';
9
12
  import { osTranslations } from '@dxos/ui-theme';
10
13
 
11
14
  import { meta } from '../meta';
12
- import { ObservabilityOperation, type UserFeedback } from '../types';
15
+ import { ObservabilityCapabilities, ObservabilityOperation, type UserFeedback } from '../types';
13
16
 
14
17
  import { FeedbackForm } from './FeedbackForm';
15
18
 
19
+ /** Renders the feedback form, disabling it when the feedback survey is unavailable. */
16
20
  export const HelpContainer = () => {
17
21
  const { invokePromise } = useOperationInvoker();
22
+ const observability = useCapability(ObservabilityCapabilities.Observability);
23
+ const [feedbackAvailable, setFeedbackAvailable] = useState(false);
24
+
25
+ useAsyncEffect(
26
+ async (controller) => {
27
+ const available = await observability.isAvailable('feedback').pipe(
28
+ Effect.catchAll(() => Effect.succeed(false)),
29
+ Effect.catchAllDefect(() => Effect.succeed(false)),
30
+ runAndForwardErrors,
31
+ );
32
+ if (!controller.signal.aborted) {
33
+ setFeedbackAvailable(available);
34
+ }
35
+ },
36
+ [observability],
37
+ );
18
38
 
19
39
  const handleSave = useCallback(
20
40
  async (values: UserFeedback) => {
21
41
  await invokePromise(ObservabilityOperation.CaptureUserFeedback, values);
22
- await invokePromise(Common.LayoutOperation.UpdateComplementary, { state: 'collapsed' });
23
- await invokePromise(Common.LayoutOperation.AddToast, {
42
+ await invokePromise(LayoutOperation.UpdateComplementary, { state: 'collapsed' });
43
+ await invokePromise(LayoutOperation.AddToast, {
24
44
  id: `${meta.id}/feedback-success`,
25
45
  icon: 'ph--paper-plane-tilt--regular',
26
46
  duration: 3000,
@@ -32,5 +52,5 @@ export const HelpContainer = () => {
32
52
  [invokePromise],
33
53
  );
34
54
 
35
- return <FeedbackForm onSave={handleSave} />;
55
+ return <FeedbackForm onSave={handleSave} disabled={!feedbackAvailable} />;
36
56
  };
@@ -5,9 +5,9 @@
5
5
  import * as Schema from 'effect/Schema';
6
6
  import React from 'react';
7
7
 
8
- import { useOperationInvoker } from '@dxos/app-framework/react';
8
+ import { useOperationInvoker } from '@dxos/app-framework/ui';
9
9
  import { Input, Message, useTranslation } from '@dxos/react-ui';
10
- import { ControlGroup, ControlItemInput, ControlPage, ControlSection } from '@dxos/react-ui-form';
10
+ import { Settings } from '@dxos/react-ui-form';
11
11
 
12
12
  import { meta } from '../meta';
13
13
  import { ObservabilityOperation } from '../types';
@@ -34,20 +34,20 @@ export const ObservabilitySettings = ({ settings }: ObservabilitySettingsCompone
34
34
  const { invokePromise } = useOperationInvoker();
35
35
 
36
36
  return (
37
- <ControlPage>
38
- <ControlSection title={t('settings title', { ns: meta.id })}>
37
+ <Settings.Root>
38
+ <Settings.Section title={t('settings title', { ns: meta.id })}>
39
39
  <Message.Root valence='info' classNames='container-max-width mbe-cardSpacingBlock'>
40
40
  <Message.Content>{t('observability description')}</Message.Content>
41
41
  </Message.Root>
42
- <ControlGroup>
43
- <ControlItemInput title={t('observability enabled label')}>
42
+ <Settings.Group>
43
+ <Settings.ItemInput title={t('observability enabled label')}>
44
44
  <Input.Switch
45
45
  checked={settings.enabled}
46
46
  onCheckedChange={(checked) => invokePromise(ObservabilityOperation.Toggle, { state: !!checked })}
47
47
  />
48
- </ControlItemInput>
49
- </ControlGroup>
50
- </ControlSection>
51
- </ControlPage>
48
+ </Settings.ItemInput>
49
+ </Settings.Group>
50
+ </Settings.Section>
51
+ </Settings.Root>
52
52
  );
53
53
  };
@@ -26,6 +26,7 @@ export const translations = [
26
26
  'help label': 'Feedback & Support',
27
27
  'feedback textarea label': 'Feedback',
28
28
  'feedback textarea placeholder': 'Please enter your feedback, technical issue, or feature request.',
29
+ 'include debug logs label': 'Include debug logs',
29
30
  'send feedback label': 'Send Feedback',
30
31
  'feedback toast label': 'Thank you for your feedback!',
31
32
  'feedback toast description': 'We will review your feedback and get back to you as soon as possible.',
@@ -26,7 +26,7 @@ export namespace ObservabilityCapabilities {
26
26
 
27
27
  export const State = Capability.make<Atom.Writable<State>>(`${meta.id}/capability/state`);
28
28
 
29
- export const Observability = Capability.make<Observability>(`${meta.id}/capability/observability`);
29
+ export const Observability = Capability.make<Observability.Observability>(`${meta.id}/capability/observability`);
30
30
  }
31
31
 
32
32
  // NOTE: This is cloned from the client plugin to avoid circular dependencies.
@@ -2,12 +2,13 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { ActivationEvent, Common } from '@dxos/app-framework';
5
+ import { ActivationEvent } from '@dxos/app-framework';
6
+ import { AppActivationEvents } from '@dxos/app-toolkit';
6
7
 
7
8
  import { meta } from '../meta';
8
9
 
9
10
  export namespace ObservabilityEvents {
10
- export const StateReady: ActivationEvent.ActivationEvent = Common.ActivationEvent.createStateEvent(meta.id);
11
+ export const StateReady: ActivationEvent.ActivationEvent = AppActivationEvents.createStateEvent(meta.id);
11
12
  }
12
13
 
13
14
  // NOTE: This is cloned from the client plugin to avoid circular dependencies.