@dxos/plugin-script 0.7.5-labs.ea4b4c2 → 0.7.5-labs.f400bbc

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 (147) hide show
  1. package/dist/lib/browser/ScriptContainer-3RFMYKTV.mjs +258 -0
  2. package/dist/lib/browser/ScriptContainer-3RFMYKTV.mjs.map +7 -0
  3. package/dist/lib/browser/{artifact-UOESRBEZ.mjs → artifact-definition-4LWPD3DH.mjs} +27 -19
  4. package/dist/lib/browser/artifact-definition-4LWPD3DH.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-45LXDWNF.mjs → chunk-5SXOHNAK.mjs} +3 -3
  6. package/dist/lib/browser/chunk-5SXOHNAK.mjs.map +7 -0
  7. package/dist/lib/browser/{ScriptContainer-AL4ZLJID.mjs → chunk-G2FYNDU4.mjs} +19 -255
  8. package/dist/lib/browser/chunk-G2FYNDU4.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-PZPYF7M4.mjs +69 -0
  10. package/dist/lib/browser/chunk-PZPYF7M4.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-ALQHMUJN.mjs → chunk-VTWBVFBK.mjs} +2 -4
  12. package/dist/lib/browser/{chunk-ALQHMUJN.mjs.map → chunk-VTWBVFBK.mjs.map} +3 -3
  13. package/dist/lib/browser/index.mjs +60 -29
  14. package/dist/lib/browser/index.mjs.map +4 -4
  15. package/dist/lib/browser/{intent-resolver-CMKQTLBG.mjs → intent-resolver-D6FPY5ZA.mjs} +2 -2
  16. package/dist/lib/browser/meta.json +1 -1
  17. package/dist/lib/browser/{react-surface-YELZNYPR.mjs → react-surface-G4C2PZ2K.mjs} +23 -7
  18. package/dist/lib/browser/react-surface-G4C2PZ2K.mjs.map +7 -0
  19. package/dist/lib/node/ScriptContainer-G6FZU4AM.cjs +274 -0
  20. package/dist/lib/node/ScriptContainer-G6FZU4AM.cjs.map +7 -0
  21. package/dist/lib/node/{artifact-PDTB4LV4.cjs → artifact-definition-BXQCFPAH.cjs} +26 -21
  22. package/dist/lib/node/artifact-definition-BXQCFPAH.cjs.map +7 -0
  23. package/dist/lib/node/chunk-ITAJ3WRW.cjs +77 -0
  24. package/dist/lib/node/chunk-ITAJ3WRW.cjs.map +7 -0
  25. package/dist/lib/node/{chunk-IID7WUQS.cjs → chunk-K3ZZWVXS.cjs} +5 -5
  26. package/dist/lib/node/chunk-K3ZZWVXS.cjs.map +7 -0
  27. package/dist/lib/node/{chunk-F5Z3DMHA.cjs → chunk-TOXBGIEI.cjs} +5 -8
  28. package/dist/lib/node/{chunk-F5Z3DMHA.cjs.map → chunk-TOXBGIEI.cjs.map} +3 -3
  29. package/dist/lib/node/{ScriptContainer-FKCNWHBW.cjs → chunk-XKYJYY3T.cjs} +62 -281
  30. package/dist/lib/node/chunk-XKYJYY3T.cjs.map +7 -0
  31. package/dist/lib/node/index.cjs +58 -30
  32. package/dist/lib/node/index.cjs.map +4 -4
  33. package/dist/lib/node/{intent-resolver-V5ASU5DW.cjs → intent-resolver-NYJFPD5B.cjs} +6 -6
  34. package/dist/lib/node/meta.json +1 -1
  35. package/dist/lib/node/{react-surface-SMMFAPZD.cjs → react-surface-EGSE3FMN.cjs} +24 -12
  36. package/dist/lib/node/react-surface-EGSE3FMN.cjs.map +7 -0
  37. package/dist/lib/node-esm/ScriptContainer-7FTCFIF3.mjs +259 -0
  38. package/dist/lib/node-esm/ScriptContainer-7FTCFIF3.mjs.map +7 -0
  39. package/dist/lib/node-esm/{artifact-IX4ZCTUF.mjs → artifact-definition-KT4DK2LQ.mjs} +26 -19
  40. package/dist/lib/node-esm/artifact-definition-KT4DK2LQ.mjs.map +7 -0
  41. package/dist/lib/node-esm/{chunk-CGF7EOGD.mjs → chunk-2AFXX34U.mjs} +3 -3
  42. package/dist/lib/node-esm/chunk-2AFXX34U.mjs.map +7 -0
  43. package/dist/lib/node-esm/{ScriptContainer-52KVAFUY.mjs → chunk-NRICF4KE.mjs} +19 -255
  44. package/dist/lib/node-esm/chunk-NRICF4KE.mjs.map +7 -0
  45. package/dist/lib/node-esm/{chunk-GXRS4YIV.mjs → chunk-S64WSJQK.mjs} +2 -4
  46. package/dist/lib/node-esm/{chunk-GXRS4YIV.mjs.map → chunk-S64WSJQK.mjs.map} +3 -3
  47. package/dist/lib/node-esm/chunk-YIWRJ25J.mjs +71 -0
  48. package/dist/lib/node-esm/chunk-YIWRJ25J.mjs.map +7 -0
  49. package/dist/lib/node-esm/index.mjs +60 -29
  50. package/dist/lib/node-esm/index.mjs.map +4 -4
  51. package/dist/lib/node-esm/{intent-resolver-75BHFRUK.mjs → intent-resolver-KLBHSMW4.mjs} +2 -2
  52. package/dist/lib/node-esm/meta.json +1 -1
  53. package/dist/lib/node-esm/{react-surface-7PHSWVOU.mjs → react-surface-7YSGHZQM.mjs} +23 -7
  54. package/dist/lib/node-esm/react-surface-7YSGHZQM.mjs.map +7 -0
  55. package/dist/types/src/ScriptPlugin.d.ts.map +1 -1
  56. package/dist/types/src/capabilities/{artifact.d.ts → artifact-definition.d.ts} +1 -1
  57. package/dist/types/src/capabilities/artifact-definition.d.ts.map +1 -0
  58. package/dist/types/src/capabilities/index.d.ts +1 -1
  59. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  60. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  61. package/dist/types/src/components/DebugPanel/DebugPanel.d.ts +1 -2
  62. package/dist/types/src/components/DebugPanel/DebugPanel.d.ts.map +1 -1
  63. package/dist/types/src/components/FrameContainer/FrameContainer.d.ts +3 -4
  64. package/dist/types/src/components/FrameContainer/FrameContainer.d.ts.map +1 -1
  65. package/dist/types/src/components/ScriptContainer.d.ts +1 -2
  66. package/dist/types/src/components/ScriptContainer.d.ts.map +1 -1
  67. package/dist/types/src/components/ScriptSettings/ScriptSettings.d.ts +1 -2
  68. package/dist/types/src/components/ScriptSettings/ScriptSettings.d.ts.map +1 -1
  69. package/dist/types/src/components/ScriptSettingsPanel.d.ts +1 -2
  70. package/dist/types/src/components/ScriptSettingsPanel.d.ts.map +1 -1
  71. package/dist/types/src/components/ScriptToolbar/ScriptToolbar.d.ts +1 -2
  72. package/dist/types/src/components/ScriptToolbar/ScriptToolbar.d.ts.map +1 -1
  73. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.d.ts +1 -2
  74. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.d.ts.map +1 -1
  75. package/dist/types/src/components/index.d.ts +2 -2
  76. package/dist/types/src/components/index.d.ts.map +1 -1
  77. package/dist/types/src/events.d.ts +4 -0
  78. package/dist/types/src/events.d.ts.map +1 -0
  79. package/dist/types/src/hooks/deploy.d.ts.map +1 -1
  80. package/dist/types/src/hooks/template.d.ts +1 -1
  81. package/dist/types/src/hooks/view.d.ts +1 -1
  82. package/dist/types/src/hooks/view.d.ts.map +1 -1
  83. package/dist/types/src/templates/chess.d.ts +1 -4
  84. package/dist/types/src/templates/chess.d.ts.map +1 -1
  85. package/dist/types/src/templates/discord.d.ts +3 -0
  86. package/dist/types/src/templates/discord.d.ts.map +1 -0
  87. package/dist/types/src/templates/forex-effect.d.ts +0 -3
  88. package/dist/types/src/templates/forex-effect.d.ts.map +1 -1
  89. package/dist/types/src/templates/forex.d.ts +0 -3
  90. package/dist/types/src/templates/forex.d.ts.map +1 -1
  91. package/dist/types/src/templates/index.d.ts.map +1 -1
  92. package/dist/types/src/translations.d.ts +3 -0
  93. package/dist/types/src/translations.d.ts.map +1 -1
  94. package/dist/types/src/types.d.ts +1 -1
  95. package/package.json +43 -43
  96. package/src/ScriptPlugin.tsx +38 -18
  97. package/src/capabilities/{artifact.ts → artifact-definition.ts} +15 -10
  98. package/src/capabilities/index.ts +1 -1
  99. package/src/capabilities/react-surface.tsx +9 -3
  100. package/src/components/DebugPanel/DebugPanel.tsx +2 -2
  101. package/src/components/FrameContainer/FrameContainer.tsx +5 -3
  102. package/src/components/TypescriptEditor/TypescriptEditor.tsx +2 -2
  103. package/src/components/index.ts +1 -1
  104. package/src/events.ts +11 -0
  105. package/src/hooks/deploy.ts +2 -2
  106. package/src/hooks/view.ts +4 -1
  107. package/src/templates/chat.ts +4 -4
  108. package/src/templates/chess.ts +42 -35
  109. package/src/templates/discord.ts +103 -0
  110. package/src/templates/forex-effect.ts +16 -17
  111. package/src/templates/forex.ts +2 -3
  112. package/src/templates/index.ts +10 -2
  113. package/src/translations.ts +3 -0
  114. package/dist/lib/browser/AutomationPanel-J3SZ5L3Y.mjs +0 -78
  115. package/dist/lib/browser/AutomationPanel-J3SZ5L3Y.mjs.map +0 -7
  116. package/dist/lib/browser/ScriptContainer-AL4ZLJID.mjs.map +0 -7
  117. package/dist/lib/browser/artifact-UOESRBEZ.mjs.map +0 -7
  118. package/dist/lib/browser/chunk-45LXDWNF.mjs.map +0 -7
  119. package/dist/lib/browser/chunk-VIX22OMB.mjs +0 -60
  120. package/dist/lib/browser/chunk-VIX22OMB.mjs.map +0 -7
  121. package/dist/lib/browser/react-surface-YELZNYPR.mjs.map +0 -7
  122. package/dist/lib/node/AutomationPanel-4M55FURO.cjs +0 -104
  123. package/dist/lib/node/AutomationPanel-4M55FURO.cjs.map +0 -7
  124. package/dist/lib/node/ScriptContainer-FKCNWHBW.cjs.map +0 -7
  125. package/dist/lib/node/artifact-PDTB4LV4.cjs.map +0 -7
  126. package/dist/lib/node/chunk-IID7WUQS.cjs.map +0 -7
  127. package/dist/lib/node/chunk-PKT5DD3O.cjs +0 -70
  128. package/dist/lib/node/chunk-PKT5DD3O.cjs.map +0 -7
  129. package/dist/lib/node/react-surface-SMMFAPZD.cjs.map +0 -7
  130. package/dist/lib/node-esm/AutomationPanel-W6SKG35R.mjs +0 -79
  131. package/dist/lib/node-esm/AutomationPanel-W6SKG35R.mjs.map +0 -7
  132. package/dist/lib/node-esm/ScriptContainer-52KVAFUY.mjs.map +0 -7
  133. package/dist/lib/node-esm/artifact-IX4ZCTUF.mjs.map +0 -7
  134. package/dist/lib/node-esm/chunk-CGF7EOGD.mjs.map +0 -7
  135. package/dist/lib/node-esm/chunk-NBAL5DXN.mjs +0 -62
  136. package/dist/lib/node-esm/chunk-NBAL5DXN.mjs.map +0 -7
  137. package/dist/lib/node-esm/react-surface-7PHSWVOU.mjs.map +0 -7
  138. package/dist/types/src/capabilities/artifact.d.ts.map +0 -1
  139. package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts +0 -17
  140. package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts.map +0 -1
  141. package/dist/types/src/components/AutomationPanel/index.d.ts +0 -4
  142. package/dist/types/src/components/AutomationPanel/index.d.ts.map +0 -1
  143. package/src/components/AutomationPanel/AutomationPanel.tsx +0 -104
  144. package/src/components/AutomationPanel/index.ts +0 -9
  145. /package/dist/lib/browser/{intent-resolver-CMKQTLBG.mjs.map → intent-resolver-D6FPY5ZA.mjs.map} +0 -0
  146. /package/dist/lib/node/{intent-resolver-V5ASU5DW.cjs.map → intent-resolver-NYJFPD5B.cjs.map} +0 -0
  147. /package/dist/lib/node-esm/{intent-resolver-75BHFRUK.mjs.map → intent-resolver-KLBHSMW4.mjs.map} +0 -0
@@ -5,12 +5,16 @@
5
5
  // @ts-ignore
6
6
 
7
7
  import { Capabilities, contributes, createIntent, defineModule, definePlugin, Events } from '@dxos/app-framework';
8
- import { type Space } from '@dxos/client/echo';
9
- import { FunctionType, ScriptType } from '@dxos/functions';
8
+ import { ScriptType } from '@dxos/functions';
10
9
  import { RefArray } from '@dxos/live-object';
11
- import { ClientCapabilities, ClientEvents } from '@dxos/plugin-client';
10
+ import { ClientEvents } from '@dxos/plugin-client';
11
+ import { DeckCapabilities, DeckEvents } from '@dxos/plugin-deck';
12
+ import { SpaceCapabilities } from '@dxos/plugin-space';
13
+ import { defineObjectForm } from '@dxos/plugin-space/types';
14
+ import { getSpace } from '@dxos/react-client/echo';
12
15
 
13
- import { Artifact, Compiler, IntentResolver, ReactSurface, ScriptSettings } from './capabilities';
16
+ import { ArtifactDefinition, Compiler, IntentResolver, ReactSurface, ScriptSettings } from './capabilities';
17
+ import { ScriptEvents } from './events';
14
18
  import { meta, SCRIPT_PLUGIN } from './meta';
15
19
  import translations from './translations';
16
20
  import { ScriptAction } from './types';
@@ -24,7 +28,7 @@ export const ScriptPlugin = () =>
24
28
  }),
25
29
  defineModule({
26
30
  id: `${meta.id}/module/compiler`,
27
- activatesOn: Events.Startup,
31
+ activatesOn: ScriptEvents.SetupCompiler,
28
32
  activate: Compiler,
29
33
  }),
30
34
  defineModule({
@@ -39,9 +43,6 @@ export const ScriptPlugin = () =>
39
43
  contributes(Capabilities.Metadata, {
40
44
  id: ScriptType.typename,
41
45
  metadata: {
42
- creationSchema: ScriptAction.CreateScriptSchema,
43
- createObject: (props: ScriptAction.CreateScriptProps, { space }: { space: Space }) =>
44
- createIntent(ScriptAction.Create, { ...props, space }),
45
46
  placeholder: ['object title placeholder', { ns: SCRIPT_PLUGIN }],
46
47
  icon: 'ph--code--regular',
47
48
  // TODO(wittjosiah): Move out of metadata.
@@ -50,26 +51,45 @@ export const ScriptPlugin = () =>
50
51
  }),
51
52
  }),
52
53
  defineModule({
53
- id: `${meta.id}/module/schema`,
54
+ id: `${meta.id}/module/complementary-panels`,
55
+ activatesOn: DeckEvents.SetupComplementaryPanels,
56
+ activate: () =>
57
+ contributes(DeckCapabilities.ComplementaryPanel, {
58
+ id: 'function',
59
+ label: ['function panel label', { ns: SCRIPT_PLUGIN }],
60
+ icon: 'ph--terminal--regular',
61
+ fixed: true,
62
+ filter: (node) => node.data instanceof ScriptType && !!getSpace(node.data),
63
+ }),
64
+ }),
65
+ defineModule({
66
+ id: `${meta.id}/module/object-form`,
54
67
  activatesOn: ClientEvents.SetupSchema,
55
- activate: () => [
56
- contributes(ClientCapabilities.SystemSchema, [FunctionType]),
57
- contributes(ClientCapabilities.Schema, [ScriptType]),
58
- ],
68
+ activate: () =>
69
+ contributes(
70
+ SpaceCapabilities.ObjectForm,
71
+ defineObjectForm({
72
+ objectSchema: ScriptType,
73
+ formSchema: ScriptAction.CreateScriptSchema,
74
+ getIntent: (props, options) => createIntent(ScriptAction.Create, { ...props, space: options.space }),
75
+ }),
76
+ ),
59
77
  }),
60
78
  defineModule({
61
79
  id: `${meta.id}/module/react-surface`,
62
- activatesOn: Events.SetupSurfaces,
80
+ activatesOn: Events.SetupReactSurface,
81
+ // TODO(wittjosiah): Should occur before the script editor is loaded when surfaces activation is more granular.
82
+ activatesBefore: [ScriptEvents.SetupCompiler],
63
83
  activate: ReactSurface,
64
84
  }),
65
85
  defineModule({
66
86
  id: `${meta.id}/module/intent-resolver`,
67
- activatesOn: Events.SetupIntents,
87
+ activatesOn: Events.SetupIntentResolver,
68
88
  activate: IntentResolver,
69
89
  }),
70
90
  defineModule({
71
- id: `${meta.id}/module/artifact`,
72
- activatesOn: Events.Startup,
73
- activate: Artifact,
91
+ id: `${meta.id}/module/artifact-definition`,
92
+ activatesOn: Events.SetupArtifactDefinition,
93
+ activate: ArtifactDefinition,
74
94
  }),
75
95
  ]);
@@ -8,10 +8,11 @@ import { createArtifactElement } from '@dxos/assistant';
8
8
  import { ObjectId, S } from '@dxos/echo-schema';
9
9
  import { ScriptType } from '@dxos/functions';
10
10
  import { invariant } from '@dxos/invariant';
11
+ import { SpaceAction } from '@dxos/plugin-space/types';
11
12
  import { create, makeRef, type Space } from '@dxos/react-client/echo';
12
13
  import { TextType } from '@dxos/schema';
13
- import { SpaceAction } from '@dxos/plugin-space/types';
14
14
 
15
+ import { meta } from '../meta';
15
16
  // TODO(burdon): Factor out.
16
17
  declare global {
17
18
  interface ToolContextExtensions {
@@ -22,10 +23,11 @@ declare global {
22
23
 
23
24
  export default () => {
24
25
  const definition = defineArtifact({
25
- id: 'plugin-script',
26
+ id: meta.id,
27
+ name: meta.name,
26
28
  // TODO(dmaretskyi): Since writing scripts requires a lot of domain knowledge,
27
- // we should offload the work of synthesizing the code to a separate model.
28
- // The main reasoning model will give it a concrete task and the script model will synthesize the code, knowing all the docs.
29
+ // we should offload the work of synthesizing the code to a separate model.
30
+ // The main reasoning model will give it a concrete task and the script model will synthesize the code, knowing all the docs.
29
31
  instructions: `
30
32
  If the user explicitly requests you to write a script, you can create one.
31
33
  If the user requests you to change one of the existing script, you can update it.
@@ -136,9 +138,10 @@ export default () => {
136
138
  `,
137
139
  schema: ScriptType,
138
140
  tools: [
139
- defineTool({
140
- name: 'script_new',
141
+ defineTool(meta.id, {
142
+ name: 'create',
141
143
  description: 'Create a new script. Returns the artifact definition for the script',
144
+ caption: 'Creating script...',
142
145
  schema: S.Struct({
143
146
  name: S.String.annotations({ description: 'The name of the script' }),
144
147
  code: S.String.annotations({
@@ -168,9 +171,10 @@ export default () => {
168
171
  return ToolResult.Success(createArtifactElement(script.id));
169
172
  },
170
173
  }),
171
- defineTool({
172
- name: 'script_inspect',
174
+ defineTool(meta.id, {
175
+ name: 'inspect',
173
176
  description: 'Inspect a script. Returns the artifact definition for the script',
177
+ caption: 'Inspecting script...',
174
178
  schema: S.Struct({
175
179
  id: ObjectId,
176
180
  }),
@@ -186,9 +190,10 @@ export default () => {
186
190
  });
187
191
  },
188
192
  }),
189
- defineTool({
190
- name: 'script_update',
193
+ defineTool(meta.id, {
194
+ name: 'update',
191
195
  description: 'Update a script. Returns the artifact definition for the script',
196
+ caption: 'Updating script...',
192
197
  schema: S.Struct({
193
198
  id: ObjectId,
194
199
  code: S.String.annotations({
@@ -8,6 +8,6 @@ export const Compiler = lazy(() => import('./compiler'));
8
8
  export const IntentResolver = lazy(() => import('./intent-resolver'));
9
9
  export const ReactSurface = lazy(() => import('./react-surface'));
10
10
  export const ScriptSettings = lazy(() => import('./settings'));
11
- export const Artifact = lazy(() => import('./artifact'));
11
+ export const ArtifactDefinition = lazy(() => import('./artifact-definition'));
12
12
 
13
13
  export * from './capabilities';
@@ -10,7 +10,8 @@ import { SettingsStore } from '@dxos/local-storage';
10
10
  import { Clipboard } from '@dxos/react-ui';
11
11
 
12
12
  import { ScriptCapabilities } from './capabilities';
13
- import { AutomationPanel, ScriptSettings, ScriptContainer, ScriptSettingsPanel } from '../components';
13
+ import { DebugPanel, ScriptSettings, ScriptContainer, ScriptSettingsPanel } from '../components';
14
+ import { useDeployState, useToolbarState } from '../hooks';
14
15
  import { SCRIPT_PLUGIN } from '../meta';
15
16
  import { type ScriptSettingsProps } from '../types';
16
17
 
@@ -36,10 +37,15 @@ export default () =>
36
37
  }),
37
38
  createSurface({
38
39
  id: `${SCRIPT_PLUGIN}/automation`,
39
- role: 'complementary--automation',
40
+ role: 'complementary--function',
40
41
  position: 'hoist',
41
42
  filter: (data): data is { subject: ScriptType } => data.subject instanceof ScriptType,
42
- component: ({ data }) => <AutomationPanel subject={data.subject} />,
43
+ component: ({ data }) => {
44
+ // TODO(wittjosiah): Decouple hooks from toolbar state.
45
+ const state = useToolbarState({ view: 'editor' });
46
+ useDeployState({ state, script: data.subject });
47
+ return <DebugPanel functionUrl={state.functionUrl} />;
48
+ },
43
49
  }),
44
50
  createSurface({
45
51
  id: `${SCRIPT_PLUGIN}/settings-panel`,
@@ -7,7 +7,7 @@ import React, { forwardRef, useEffect, useRef, useState } from 'react';
7
7
  import { log } from '@dxos/log';
8
8
  import { Avatar, Icon, Input, type ThemedClassName, Toolbar, useTranslation } from '@dxos/react-ui';
9
9
  import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
10
- import { mx } from '@dxos/react-ui-theme';
10
+ import { errorText, mx } from '@dxos/react-ui-theme';
11
11
 
12
12
  import { SCRIPT_PLUGIN } from '../../meta';
13
13
 
@@ -232,7 +232,7 @@ const MessageItem = ({ classNames, message }: ThemedClassName<{ message: Message
232
232
  const wrapper = 'p-1 px-2 rounded-lg bg-hoverSurface overflow-auto';
233
233
  return (
234
234
  <div className={mx('flex', type === 'request' ? 'ml-[1rem] justify-end' : 'mr-[1rem]', classNames)}>
235
- {error && <div className={mx(wrapper, 'whitespace-pre text-error')}>{String(error)}</div>}
235
+ {error && <div className={mx(wrapper, 'whitespace-pre', errorText)}>{String(error)}</div>}
236
236
 
237
237
  {text !== undefined && (
238
238
  <div className={mx(wrapper, type === 'request' && 'bg-primary-400 dark:bg-primary-600')}>
@@ -5,7 +5,8 @@
5
5
  import React, { useEffect, useRef } from 'react';
6
6
 
7
7
  import { clientServiceBundle } from '@dxos/client-protocol';
8
- import { type BundlerResult } from '@dxos/functions/bundler';
8
+ import { type BundleResult } from '@dxos/functions/bundler';
9
+ import { invariant } from '@dxos/invariant';
9
10
  import { log } from '@dxos/log';
10
11
  import { useClient } from '@dxos/react-client';
11
12
  import { baseSurface, mx } from '@dxos/react-ui-theme';
@@ -14,7 +15,7 @@ import { createIFramePort } from '@dxos/rpc-tunnel';
14
15
 
15
16
  export type FrameContainerProps = {
16
17
  containerUrl: string;
17
- result: BundlerResult;
18
+ result: BundleResult;
18
19
  debug?: boolean;
19
20
  };
20
21
 
@@ -45,6 +46,7 @@ export const FrameContainer = ({ containerUrl, result, debug = true }: FrameCont
45
46
  }, [iframeRef]);
46
47
 
47
48
  // Encodes compiled code via URL.
49
+ invariant(result.sourceHash, 'Source hash is required.');
48
50
  const sourceHash = Buffer.from(result.sourceHash).toString('hex');
49
51
  const src = result.bundle && `${containerUrl}?ts=${sourceHash}#code=${encodeURIComponent(result.bundle)}`;
50
52
 
@@ -57,7 +59,7 @@ export const FrameContainer = ({ containerUrl, result, debug = true }: FrameCont
57
59
  <div
58
60
  className={mx(
59
61
  baseSurface,
60
- 'flex absolute right-2 bottom-2 w-[400px] h-[200px] ring rounded',
62
+ 'flex absolute right-2 bottom-2 w-[30rem] h-[200px] ring rounded',
61
63
  'z-20 overflow-x-hidden overflow-y-auto',
62
64
  )}
63
65
  >
@@ -27,7 +27,7 @@ import {
27
27
  useTextEditor,
28
28
  type UseTextEditorProps,
29
29
  } from '@dxos/react-ui-editor';
30
- import { nonNullable } from '@dxos/util';
30
+ import { isNonNullable } from '@dxos/util';
31
31
 
32
32
  export type TypescriptEditorProps = {
33
33
  id: string;
@@ -94,7 +94,7 @@ export const TypescriptEditor = ({
94
94
  ]
95
95
  : [],
96
96
  ],
97
- ].filter(nonNullable),
97
+ ].filter(isNonNullable),
98
98
  selection,
99
99
  scrollTo,
100
100
  }),
@@ -4,8 +4,8 @@
4
4
 
5
5
  import { lazy } from 'react';
6
6
 
7
+ export * from './DebugPanel';
7
8
  export * from './ScriptSettings';
8
9
  export * from './ScriptSettingsPanel';
9
10
 
10
- export const AutomationPanel = lazy(() => import('./AutomationPanel'));
11
11
  export const ScriptContainer = lazy(() => import('./ScriptContainer'));
package/src/events.ts ADDED
@@ -0,0 +1,11 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { defineEvent } from '@dxos/app-framework';
6
+
7
+ import { SCRIPT_PLUGIN } from './meta';
8
+
9
+ export namespace ScriptEvents {
10
+ export const SetupCompiler = defineEvent(`${SCRIPT_PLUGIN}/event/setup-compiler`);
11
+ }
@@ -6,10 +6,10 @@ import { useCallback, useEffect, useMemo } from 'react';
6
6
 
7
7
  import {
8
8
  FunctionType,
9
+ type ScriptType,
9
10
  getInvocationUrl,
10
11
  getUserFunctionUrlInMetadata,
11
12
  incrementSemverPatch,
12
- type ScriptType,
13
13
  setUserFunctionUrlInMetadata,
14
14
  uploadWorkerFunction,
15
15
  } from '@dxos/functions';
@@ -105,7 +105,7 @@ export const useDeployHandler = ({ state, script }: { state: Partial<DeployState
105
105
  const existingFunctionId = existingFunctionUrl?.split('/').at(-1);
106
106
 
107
107
  const bundler = new Bundler({ platform: 'browser', sandboxedModules: [], remoteModules: {} });
108
- const buildResult = await bundler.bundle(script.source.target!.content);
108
+ const buildResult = await bundler.bundle({ source: script.source.target!.content });
109
109
  if (buildResult.error || !buildResult.bundle) {
110
110
  throw buildResult.error;
111
111
  }
package/src/hooks/view.ts CHANGED
@@ -6,7 +6,8 @@ import { createMenuAction, createMenuItemGroup } from '@dxos/react-ui-menu';
6
6
 
7
7
  import { SCRIPT_PLUGIN } from '../meta';
8
8
 
9
- export type ViewType = 'editor' | 'split' | 'debug';
9
+ // TODO(wittjosiah): Replace debug with logs.
10
+ export type ViewType = 'editor' | 'split' | 'debug'; // 'logs';
10
11
 
11
12
  export type ViewState = { view: ViewType };
12
13
 
@@ -16,6 +17,8 @@ const views: Record<ViewType, string> = {
16
17
  editor: 'ph--code--regular',
17
18
  split: 'ph--square-split-vertical--regular',
18
19
  debug: 'ph--bug--regular',
20
+ // TODO(wittjosiah): Replace debug with logs.
21
+ // logs: 'ph--clock-counter-clockwise--regular',
19
22
  };
20
23
 
21
24
  const createViewGroupItem = (state: Partial<ViewState>) => {
@@ -57,11 +57,11 @@ export default async ({
57
57
  let prompt = promptObject.template;
58
58
  for (const input of promptObject.inputs) {
59
59
  let value: string | null = null;
60
- if (input.type === ChainInputType.VALUE) {
60
+ if (input.type === TemplateInputType.VALUE) {
61
61
  value = String(input.value);
62
- } else if (input.type === ChainInputType.RETRIEVER) {
62
+ } else if (input.type === TemplateInputType.RETRIEVER) {
63
63
  value = await getContext({ space });
64
- } else if (input.type === ChainInputType.PASS_THROUGH) {
64
+ } else if (input.type === TemplateInputType.PASS_THROUGH) {
65
65
  value = message.text;
66
66
  }
67
67
  if (value) {
@@ -90,7 +90,7 @@ const getContext = async ({ space }: any) => {
90
90
  return context;
91
91
  };
92
92
 
93
- enum ChainInputType {
93
+ enum TemplateInputType {
94
94
  VALUE = 0,
95
95
  PASS_THROUGH = 1,
96
96
  RETRIEVER = 2,
@@ -1,41 +1,48 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
1
+ // @ts-ignore
2
+ import { defineFunction, S } from 'dxos:functions';
5
3
  // @ts-ignore
6
4
  import { Chess } from 'https://esm.sh/chess.js@0.13.1';
7
5
 
8
- /**
9
- * Plays a random move in a chess game.
10
- */
11
- export default async ({
12
- event: {
13
- data: { request },
14
- },
15
- context: { space },
16
- }: any) => {
17
- const {
18
- data: {
19
- objects: [gameId],
20
- player = 'b',
21
- },
22
- } = await request.json();
6
+ export default defineFunction({
7
+ description: 'Plays a random move in a chess game.',
23
8
 
24
- const { pgn } = await space.crud.query({ id: gameId }).first();
25
- const game = new Chess();
26
- game.load_pgn(pgn);
27
- if (game.turn() !== player) {
28
- return new Response('Invalid turn', { status: 409 });
29
- }
9
+ inputSchema: S.Struct({
10
+ changedObjectId: S.String.annotations({
11
+ description: 'The objects to play the game on.',
12
+ }),
13
+ player: S.optional(S.Literal('w', 'b')).annotations({
14
+ description: 'The player to play the game as.',
15
+ }),
16
+ }),
30
17
 
31
- const moves = game.moves();
32
- const move = moves[Math.floor(Math.random() * moves.length)];
33
- if (!move) {
34
- return new Response('No legal moves', { status: 406 });
35
- }
18
+ outputSchema: S.Struct({
19
+ state: S.String.annotations({
20
+ description: 'The state of the game as an ASCII art board.',
21
+ }),
22
+ }),
36
23
 
37
- game.move(move);
38
- const newPgn = game.pgn();
39
- await space.crud.update({ id: gameId }, { pgn: newPgn });
40
- return new Response(game.ascii());
41
- };
24
+ handler: async ({
25
+ event: {
26
+ data: { changedObjectId, player = 'b' },
27
+ },
28
+ context: { space },
29
+ }: any) => {
30
+ const { pgn } = await space.db.query({ id: changedObjectId }).first();
31
+ const game = new Chess();
32
+ game.load_pgn(pgn);
33
+ if (game.turn() !== player) {
34
+ return new Response('Invalid turn', { status: 409 });
35
+ }
36
+
37
+ const moves = game.moves();
38
+ const move = moves[Math.floor(Math.random() * moves.length)];
39
+ if (!move) {
40
+ return new Response('No legal moves', { status: 406 });
41
+ }
42
+
43
+ game.move(move);
44
+ const newPgn = game.pgn();
45
+ await space.db.update({ id: changedObjectId }, { pgn: newPgn, fen: game.fen() });
46
+ return { state: game.ascii() };
47
+ },
48
+ });
@@ -0,0 +1,103 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ // @ts-ignore
6
+ import { createStatic, EchoObject, defineFunction, DXN, Filter, ObjectId, S } from 'dxos:functions';
7
+ import {
8
+ FetchHttpClient,
9
+ // @ts-ignore
10
+ } from 'https://esm.sh/@effect/platform@0.77.2?deps=effect@3.13.3';
11
+ // @ts-ignore
12
+ import { DiscordConfig, DiscordREST, DiscordRESTMemoryLive } from 'https://esm.sh/dfx@0.113.0?deps=effect@3.13.3';
13
+ // @ts-ignore
14
+ import { Effect, Config, Redacted, Ref } from 'https://esm.sh/effect@3.13.3';
15
+
16
+ const MessageSchema = S.Struct({
17
+ id: S.String,
18
+ foreignId: S.Any, // bigint?
19
+ from: S.String,
20
+ created: S.String,
21
+ content: S.String,
22
+ }).pipe(EchoObject('example.com/type/Message', '0.1.0'));
23
+
24
+ const DEFAULT_AFTER = 1704067200; // 2024-01-01
25
+
26
+ const generateSnowflake = (unixTimestamp: number): bigint => {
27
+ const discordEpoch = 1420070400000n; // Discord Epoch (ms)
28
+ return (BigInt(unixTimestamp * 1000) - discordEpoch) << 22n;
29
+ };
30
+
31
+ export default defineFunction({
32
+ inputSchema: S.Struct({
33
+ // TODO(wittjosiah): Remove. This is used to provide a terminal for a cron trigger.
34
+ tick: S.optional(S.String),
35
+ channelId: S.String,
36
+ after: S.optional(S.Number),
37
+ pageSize: S.optional(S.Number),
38
+ queueId: S.String,
39
+ }),
40
+
41
+ outputSchema: S.Struct({
42
+ newMessages: S.Number,
43
+ }),
44
+
45
+ handler: ({
46
+ event: {
47
+ data: { channelId, queueId, after = DEFAULT_AFTER, pageSize = 5 },
48
+ },
49
+ context: { space },
50
+ }: any) =>
51
+ Effect.gen(function* () {
52
+ const { token } = yield* Effect.tryPromise(() =>
53
+ space.db.query(Filter.typename('dxos.org/type/AccessToken', { source: 'discord.com' })).first(),
54
+ );
55
+ const { objects } = yield* Effect.tryPromise(() => space.queues.queryQueue(DXN.parse(queueId)));
56
+ const backfill = objects.length === 0;
57
+ const newMessages = yield* Ref.make(0);
58
+ const lastMessage = yield* Ref.make(objects.at(-1));
59
+
60
+ const enqueueMessages = Effect.gen(function* () {
61
+ const rest = yield* DiscordREST;
62
+
63
+ while (true) {
64
+ const last = yield* Ref.get(lastMessage);
65
+ const options = {
66
+ after: backfill && !last ? `${generateSnowflake(after)}` : last?.foreignId,
67
+ limit: pageSize,
68
+ };
69
+ const messages = yield* rest.getChannelMessages(channelId, options).pipe((res: any) => res.json);
70
+ const queueMessages = messages
71
+ .map((message: any) =>
72
+ createStatic(MessageSchema, {
73
+ id: ObjectId.random(),
74
+ foreignId: message.id,
75
+ from: message.author.username,
76
+ created: message.timestamp,
77
+ content: message.content,
78
+ }),
79
+ )
80
+ .toReversed();
81
+ if (queueMessages.length > 0) {
82
+ yield* Effect.tryPromise(() => space.queues.insertIntoQueue(DXN.parse(queueId), queueMessages));
83
+ yield* Ref.update(newMessages, (n: any) => n + queueMessages.length);
84
+ yield* Ref.update(lastMessage, (m: any) => queueMessages.at(-1));
85
+ }
86
+ if (messages.length < pageSize) {
87
+ break;
88
+ }
89
+ }
90
+ }).pipe(
91
+ Effect.provide(DiscordRESTMemoryLive),
92
+ Effect.provide(
93
+ DiscordConfig.layerConfig({
94
+ token: Config.succeed(Redacted.make(token)),
95
+ }),
96
+ ),
97
+ Effect.provide(FetchHttpClient.layer),
98
+ );
99
+
100
+ yield* enqueueMessages;
101
+ return { newMessages: yield* Ref.get(newMessages) };
102
+ }),
103
+ });
@@ -7,36 +7,35 @@ import { defineFunction, S } from 'dxos:functions';
7
7
  import {
8
8
  HttpClient,
9
9
  HttpClientRequest,
10
- HttpClientResponse,
11
- HttpClientError,
10
+ FetchHttpClient,
12
11
  // @ts-ignore
13
- } from 'https://esm.sh/@effect/platform@0.61.0?deps=effect@3.6.0';
12
+ } from 'https://esm.sh/@effect/platform@0.77.2?deps=effect@3.13.3';
14
13
  // @ts-ignore
15
- import type { Cause } from 'https://esm.sh/effect@3.6.0';
16
- // @ts-ignore
17
- import { Effect, Schedule } from 'https://esm.sh/effect@3.6.0';
14
+ import { Effect, Schedule } from 'https://esm.sh/effect@3.13.3';
18
15
 
19
- /**
20
- * Returns the exchange rate between two currencies.
21
- */
22
16
  export default defineFunction({
17
+ description: 'Returns the exchange rate between two currencies.',
18
+
23
19
  inputSchema: S.Struct({
24
20
  from: S.String.annotations({ description: 'The source currency' }),
25
21
  to: S.String.annotations({ description: 'The target currency' }),
26
22
  }),
27
23
 
28
- outputSchema: S.String,
24
+ outputSchema: S.String.annotations({ description: 'The exchange rate between the two currencies' }),
29
25
 
30
26
  handler: async ({
31
27
  event: {
32
28
  data: { from, to },
33
29
  },
34
30
  }: any) =>
35
- HttpClientRequest.get(`https://free.ratesdb.com/v1/rates?from=${from}&to=${to}`).pipe(
36
- HttpClient.fetchOk,
37
- HttpClientResponse.json,
38
- Effect.timeout('1 second'),
39
- Effect.retry(Schedule.exponential(1000).pipe(Schedule.compose(Schedule.recurs(3)))),
40
- Effect.map(({ data: { rates } }: any) => rates[to].toString()),
41
- ),
31
+ Effect.gen(function* () {
32
+ const res = yield* HttpClientRequest.get(`https://free.ratesdb.com/v1/rates?from=${from}&to=${to}`).pipe(
33
+ HttpClient.execute,
34
+ Effect.flatMap((res: any) => res.json),
35
+ Effect.timeout('1 second'),
36
+ Effect.retry(Schedule.exponential(1000).pipe(Schedule.compose(Schedule.recurs(3)))),
37
+ Effect.scoped,
38
+ );
39
+ return res.data.rates[to].toString();
40
+ }).pipe(Effect.provide(FetchHttpClient.layer)),
42
41
  });
@@ -5,10 +5,9 @@
5
5
  // @ts-ignore
6
6
  import { defineFunction, S } from 'dxos:functions';
7
7
 
8
- /**
9
- * Returns the exchange rate between two currencies.
10
- */
11
8
  export default defineFunction({
9
+ description: 'Returns the exchange rate between two currencies.',
10
+
12
11
  inputSchema: S.Struct({
13
12
  from: S.String.annotations({ description: 'The source currency' }),
14
13
  to: S.String.annotations({ description: 'The target currency' }),
@@ -7,13 +7,15 @@ import chat from './chat.ts?raw';
7
7
  // @ts-ignore
8
8
  import chess from './chess.ts?raw';
9
9
  // @ts-ignore
10
+ import discord from './discord.ts?raw';
11
+ // @ts-ignore
10
12
  import echo from './echo.ts?raw';
11
13
  // @ts-ignore
12
14
  import email from './email.ts?raw';
13
15
  // @ts-ignore
14
- import forex from './forex.ts?raw';
15
- // @ts-ignore
16
16
  import forexEffect from './forex-effect.ts?raw';
17
+ // @ts-ignore
18
+ import forex from './forex.ts?raw';
17
19
 
18
20
  const removeHeader = (str: string) => str.split('\n').slice(4).join('\n');
19
21
 
@@ -58,4 +60,10 @@ export const templates: Template[] = [
58
60
  source: removeHeader(email),
59
61
  presetId: 'dxos.org/function/email',
60
62
  },
63
+ {
64
+ id: 'dxos.org/script/discord',
65
+ name: 'Discord',
66
+ source: removeHeader(discord),
67
+ presetId: 'dxos.org/function/discord',
68
+ },
61
69
  ];
@@ -49,7 +49,10 @@ export default [
49
49
  'view editor label': 'Editor',
50
50
  'view split label': 'Split',
51
51
  'view debug label': 'Debug',
52
+ // TODO(wittjosiah): Replace debug with logs.
53
+ // 'view logs label': 'Logs',
52
54
  'template select group label': 'Select template',
55
+ 'function panel label': 'Debug Function',
53
56
  },
54
57
  },
55
58
  },