tassello 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +175 -8
  3. package/dist/server/behavior_tree_files.d.ts +0 -1
  4. package/dist/server/behavior_tree_files.js +2 -25
  5. package/dist/server/diagnostics.d.ts +16 -0
  6. package/dist/server/diagnostics.js +200 -0
  7. package/dist/server/diagnostics_state.d.ts +23 -0
  8. package/dist/server/diagnostics_state.js +146 -0
  9. package/dist/server/disks.d.ts +14 -0
  10. package/dist/server/disks.js +152 -0
  11. package/dist/server/file_manager.d.ts +25 -0
  12. package/dist/server/file_manager.js +717 -0
  13. package/dist/server/http.js +248 -5
  14. package/dist/server/netpbm.d.ts +3 -0
  15. package/dist/server/netpbm.js +69 -0
  16. package/dist/server/networking.d.ts +41 -0
  17. package/dist/server/networking.js +508 -0
  18. package/dist/server/networking_format.d.ts +38 -0
  19. package/dist/server/networking_format.js +651 -0
  20. package/dist/server/pty.d.ts +26 -0
  21. package/dist/server/pty.js +150 -0
  22. package/dist/server/server.js +13 -2
  23. package/dist/server/session.d.ts +10 -1
  24. package/dist/server/session.js +88 -1
  25. package/dist/server/terminal_output.d.ts +25 -0
  26. package/dist/server/terminal_output.js +108 -0
  27. package/dist/server/terminals.d.ts +32 -0
  28. package/dist/server/terminals.js +366 -0
  29. package/dist/server/util.d.ts +4 -0
  30. package/dist/server/util.js +45 -1
  31. package/dist/shared/file_manager.d.ts +130 -0
  32. package/dist/shared/file_manager.js +7 -0
  33. package/dist/shared/networking.d.ts +178 -0
  34. package/dist/shared/networking.js +248 -0
  35. package/dist/shared/protocol.d.ts +103 -2
  36. package/dist/shared/protocol.js +8 -0
  37. package/dist/types/client/api.d.ts +22 -0
  38. package/dist/types/client/connection.d.ts +30 -1
  39. package/dist/types/client/icons.d.ts +33 -0
  40. package/dist/types/client/sdk/index.d.ts +5 -3
  41. package/dist/types/shared/file_manager.d.ts +130 -0
  42. package/dist/types/shared/networking.d.ts +178 -0
  43. package/dist/types/shared/protocol.d.ts +103 -2
  44. package/dist/www/assets/Joystick.js +1 -1
  45. package/dist/www/assets/RobotModelView.js +2 -2
  46. package/dist/www/assets/TerminalView.css +1 -0
  47. package/dist/www/assets/TerminalView.js +17 -0
  48. package/dist/www/assets/dialogs.js +1 -0
  49. package/dist/www/assets/icons.js +1 -1
  50. package/dist/www/assets/index.css +1 -1
  51. package/dist/www/assets/index.js +59 -19
  52. package/dist/www/assets/keys.js +3 -0
  53. package/dist/www/assets/shared/tassello-sdk.js +1 -1
  54. package/dist/www/index.html +2 -0
  55. package/docs/plugins.md +22 -0
  56. package/package.json +6 -2
@@ -56,3 +56,36 @@ export declare const BanIcon: (props: SVGProps<SVGSVGElement>) => import("react"
56
56
  export declare const FilterIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
57
57
  export declare const DownloadIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
58
58
  export declare const ArrowDownToLineIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
59
+ export declare const DiagnosticsIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
60
+ export declare const UnfoldIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
61
+ export declare const FolderIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
62
+ export declare const FolderPlusIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
63
+ export declare const FileIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
64
+ export declare const FileTextIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
65
+ export declare const FilePlusIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
66
+ export declare const UploadIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
67
+ export declare const ArrowUpIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
68
+ export declare const ArrowLeftIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
69
+ export declare const HomeIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
70
+ export declare const HardDriveIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
71
+ export declare const BookmarkIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
72
+ export declare const SidebarIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
73
+ export declare const PieChartIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
74
+ export declare const InfoIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
75
+ export declare const WrapIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
76
+ export declare const LinkIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
77
+ export declare const LockIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
78
+ export declare const ArchiveIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
79
+ export declare const ShellIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
80
+ export declare const KeyboardIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
81
+ export declare const MaximizeIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
82
+ export declare const MinimizeIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
83
+ export declare const ClipboardIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
84
+ export declare const TextSmallerIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
85
+ export declare const TextLargerIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
86
+ export declare const NetworkIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
87
+ export declare const WifiIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
88
+ export declare const WifiOffIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
89
+ export declare const EthernetIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
90
+ export declare const HotspotIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
91
+ export declare const ShieldIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
@@ -1,10 +1,12 @@
1
1
  export { defineWidget, definePlugin, type WidgetDefinition, type WidgetProps, type PropertySchema, type Property, type RegisteredWidget, type TasselloClientPlugin, } from '../widgets/types.ts';
2
- export { connection, useConnectionStatus, useTopic, useTf, useCommandState, type BehaviorTreeFileHandlers, type BehaviorTreeFileOptions, type BehaviorTreeHandlers, type BehaviorTreeOptions, type BehaviorTreePlaybackOptions, type BehaviorTreePlaybackRequest, type Connection, type ConnectionStatus, type TopicState, type TopicHandlers, type TopicOptions, type PluginStreamHandlers, type RosoutHandlers, type RosoutOptions, type StreamHandlers, type FrameInfo, type ImageOptions, type TfOptions, } from '../connection.ts';
3
- export { imageUrl } from '../api.ts';
2
+ export { connection, useConnectionStatus, useTopic, useTf, useCommandState, type BehaviorTreeFileHandlers, type BehaviorTreeFileOptions, type BehaviorTreeHandlers, type BehaviorTreeOptions, type BehaviorTreePlaybackOptions, type BehaviorTreePlaybackRequest, type Connection, type ConnectionStatus, type TopicState, type TopicHandlers, type TopicOptions, type PluginStreamHandlers, type RosoutHandlers, type RosoutOptions, type DiagnosticsHandlers, type DiagnosticsOptions, type TerminalHandlers, type TerminalOptions, type StreamHandlers, type FrameInfo, type ImageOptions, type TfOptions, } from '../connection.ts';
3
+ export { imageUrl, fsApi, ApiError, type Upload } from '../api.ts';
4
4
  export { useDialogs, Modal, type Dialogs, type ConfirmOptions, type PromptOptions } from '../dialogs.tsx';
5
5
  export { notify } from '../notifications.tsx';
6
6
  export { Joystick, type JoystickProps } from '../widgets/Joystick.tsx';
7
7
  export * from '../icons.tsx';
8
- export type { BehaviorTreeFile, BehaviorTreeInfo, BehaviorTreeModels, BehaviorTreePlaybackState, BehaviorTreeRecording, BehaviorTreeSaved, BehaviorTreeUpdate, BtNode, BtNodeLibrary, BtNodeState, BtTransition, CommandState, ClientMessage, LogEntry, RosoutUpdate, ServerMessage, StreamStatus, TfUpdate, Transform2D, } from '../../shared/protocol.ts';
8
+ export type { BehaviorTreeFile, BehaviorTreeInfo, BehaviorTreeModels, BehaviorTreePlaybackState, BehaviorTreeRecording, BehaviorTreeSaved, BehaviorTreeUpdate, BtNode, BtNodeLibrary, BtNodeState, BtTransition, CommandState, ClientMessage, DiagnosticChange, DiagnosticEntry, DiagnosticsUpdate, LogEntry, NetworkUpdate, RosoutUpdate, ServerMessage, StreamStatus, TerminalExit, TerminalOutput, TfUpdate, Transform2D, } from '../../shared/protocol.ts';
9
9
  export type { BtNodeModel, BtPortModel } from '../../shared/bt_nodes.ts';
10
+ export type { ConnectionKind, NetworkActivity, NetworkConnection, NetworkDevice, NetworkPermissions, NetworkRequest, NetworkResult, NetworkSecrets, NetworkSettings, NetworkState, WifiNetwork, WifiSecurity, } from '../../shared/networking.ts';
11
+ export type { FsAnalysis, FsConflict, FsDetails, FsDisk, FsEntry, FsListing, FsOperation, FsPlaces, FsResult, FsSaved, FsSpace, FsText, } from '../../shared/file_manager.ts';
10
12
  export type { Panel, WidgetInstance } from '../../shared/panel.ts';
@@ -0,0 +1,130 @@
1
+ export interface FsEntry {
2
+ name: string;
3
+ kind: 'dir' | 'file' | 'other';
4
+ link: string | null;
5
+ size: number;
6
+ modified: number;
7
+ mode: number;
8
+ owner: string;
9
+ group: string;
10
+ readable: boolean;
11
+ writable: boolean;
12
+ bag: boolean;
13
+ }
14
+ export interface FsSpace {
15
+ mount: string;
16
+ total: number;
17
+ free: number;
18
+ }
19
+ export interface FsListing {
20
+ path: string;
21
+ parent: string | null;
22
+ entries: FsEntry[];
23
+ truncated: number;
24
+ writable: boolean;
25
+ version: string;
26
+ space: FsSpace | null;
27
+ }
28
+ export interface FsPlaces {
29
+ home: string;
30
+ user: string;
31
+ ros: {
32
+ name: string;
33
+ path: string;
34
+ }[];
35
+ }
36
+ export interface FsDetails extends FsEntry {
37
+ path: string;
38
+ realPath: string | null;
39
+ created: number | null;
40
+ accessed: number;
41
+ changed: number;
42
+ inode: number;
43
+ links: number;
44
+ items: number | null;
45
+ hidden: number | null;
46
+ space: FsSpace | null;
47
+ }
48
+ export interface FsDisk extends FsSpace {
49
+ device: string;
50
+ type: string;
51
+ readOnly: boolean;
52
+ used: number;
53
+ inodes: {
54
+ total: number;
55
+ free: number;
56
+ } | null;
57
+ }
58
+ export interface FsAnalysis {
59
+ path: string;
60
+ size: number;
61
+ disk: number;
62
+ files: number;
63
+ folders: number;
64
+ links: number;
65
+ children: {
66
+ name: string;
67
+ kind: FsEntry['kind'];
68
+ size: number;
69
+ files: number;
70
+ }[];
71
+ types: {
72
+ type: string;
73
+ files: number;
74
+ size: number;
75
+ }[];
76
+ largest: {
77
+ path: string;
78
+ size: number;
79
+ }[];
80
+ recent: {
81
+ path: string;
82
+ modified: number;
83
+ }[];
84
+ partial: string | null;
85
+ unreadable: number;
86
+ mounts: number;
87
+ elapsedMs: number;
88
+ }
89
+ export interface FsText {
90
+ path: string;
91
+ text: string;
92
+ version: string;
93
+ stamp: string;
94
+ readOnly: string | null;
95
+ }
96
+ export interface FsSaved {
97
+ version: string;
98
+ stamp: string;
99
+ conflict: boolean;
100
+ }
101
+ export type FsConflict = 'ask' | 'skip' | 'keep-both' | 'replace';
102
+ export type FsOperation = {
103
+ op: 'mkdir';
104
+ path: string;
105
+ } | {
106
+ op: 'create';
107
+ path: string;
108
+ } | {
109
+ op: 'rename';
110
+ path: string;
111
+ name: string;
112
+ } | {
113
+ op: 'move' | 'copy';
114
+ paths: string[];
115
+ to: string;
116
+ conflict: FsConflict;
117
+ } | {
118
+ op: 'delete';
119
+ paths: string[];
120
+ } | {
121
+ op: 'chmod';
122
+ path: string;
123
+ mode: number;
124
+ };
125
+ export interface FsResult {
126
+ paths: string[];
127
+ conflicts: string[];
128
+ }
129
+ export declare const FS_MAX_ENTRIES = 5000;
130
+ export declare const FS_MAX_TEXT_BYTES: number;
@@ -0,0 +1,178 @@
1
+ export type WifiSecurity = 'open' | 'owe' | 'wep' | 'wpa-psk' | 'sae' | 'wpa-eap';
2
+ export type ConnectionKind = 'wifi' | 'hotspot' | 'ethernet' | 'vpn' | 'other';
3
+ export type EditableKind = 'wifi' | 'hotspot' | 'ethernet';
4
+ export type Ipv4Method = 'auto' | 'manual' | 'shared' | 'disabled';
5
+ export declare const DEVICE_UNMANAGED = 10;
6
+ export declare const DEVICE_UNAVAILABLE = 20;
7
+ export declare const DEVICE_DISCONNECTED = 30;
8
+ export declare const DEVICE_ACTIVATED = 100;
9
+ export declare const DEVICE_DEACTIVATING = 110;
10
+ export declare const DEVICE_FAILED = 120;
11
+ export interface NetworkDevice {
12
+ name: string;
13
+ type: string;
14
+ state: number;
15
+ stateText: string;
16
+ reason: string;
17
+ connection: string | null;
18
+ connectionName: string;
19
+ external: boolean;
20
+ software: boolean;
21
+ hwaddr: string;
22
+ mtu: number | null;
23
+ carrier: boolean | null;
24
+ speed: string;
25
+ driver: string;
26
+ vendor: string;
27
+ product: string;
28
+ accessPoint: boolean;
29
+ band24: boolean;
30
+ band5: boolean;
31
+ ipv4: string[];
32
+ ipv6: string[];
33
+ gateway: string;
34
+ dns: string[];
35
+ }
36
+ export interface NetworkConnection {
37
+ uuid: string;
38
+ name: string;
39
+ type: string;
40
+ kind: ConnectionKind;
41
+ interface: string;
42
+ autoconnect: boolean;
43
+ priority: number;
44
+ lastUsed: number | null;
45
+ readOnly: boolean;
46
+ file: string;
47
+ device: string | null;
48
+ activeState: string | null;
49
+ external: boolean;
50
+ ssid: string;
51
+ security: WifiSecurity | null;
52
+ hidden: boolean;
53
+ band: '' | 'a' | 'bg';
54
+ channel: number;
55
+ identity: string;
56
+ vpnService: string;
57
+ ipv4Method: string;
58
+ addresses: string[];
59
+ gateway: string;
60
+ dns: string[];
61
+ }
62
+ export interface WifiNetwork {
63
+ ssid: string;
64
+ device: string;
65
+ bssid: string;
66
+ signal: number;
67
+ frequency: number;
68
+ channel: number;
69
+ rate: string;
70
+ securityText: string;
71
+ security: WifiSecurity;
72
+ mode: string;
73
+ active: boolean;
74
+ points: number;
75
+ }
76
+ export interface NetworkActivity {
77
+ id: number;
78
+ action: NetworkRequest['action'];
79
+ label: string;
80
+ uuid: string | null;
81
+ ssid: string | null;
82
+ device: string | null;
83
+ started: number;
84
+ finished: number | null;
85
+ error: string | null;
86
+ }
87
+ export interface NetworkPermissions {
88
+ control: boolean;
89
+ modify: boolean;
90
+ wifi: boolean;
91
+ scan: boolean;
92
+ share: boolean;
93
+ }
94
+ export interface NetworkState {
95
+ error: string | null;
96
+ version: string;
97
+ state: string;
98
+ connectivity: string;
99
+ wifi: boolean;
100
+ wifiHardware: boolean;
101
+ permissions: NetworkPermissions;
102
+ devices: NetworkDevice[];
103
+ connections: NetworkConnection[];
104
+ networks: WifiNetwork[];
105
+ scanning: boolean;
106
+ activity: NetworkActivity[];
107
+ }
108
+ export interface NetworkSettings {
109
+ kind: EditableKind;
110
+ name: string;
111
+ interface: string;
112
+ autoconnect: boolean;
113
+ priority: number;
114
+ ssid: string;
115
+ hidden: boolean;
116
+ security: WifiSecurity;
117
+ password: string | null;
118
+ identity: string;
119
+ band: '' | 'a' | 'bg';
120
+ channel: number;
121
+ ipv4: Ipv4Method;
122
+ addresses: string[];
123
+ gateway: string;
124
+ dns: string[];
125
+ }
126
+ export type NetworkRequest = {
127
+ action: 'connect';
128
+ uuid: string;
129
+ device: string | null;
130
+ password: string | null;
131
+ } | {
132
+ action: 'disconnect';
133
+ uuid: string;
134
+ } | {
135
+ action: 'create';
136
+ settings: NetworkSettings;
137
+ connect: boolean;
138
+ device: string | null;
139
+ } | {
140
+ action: 'modify';
141
+ uuid: string;
142
+ settings: NetworkSettings;
143
+ } | {
144
+ action: 'delete';
145
+ uuid: string;
146
+ } | {
147
+ action: 'wifi';
148
+ enabled: boolean;
149
+ } | {
150
+ action: 'rescan';
151
+ device: string | null;
152
+ } | {
153
+ action: 'secrets';
154
+ uuid: string;
155
+ };
156
+ export interface NetworkSecrets {
157
+ ssid: string;
158
+ security: WifiSecurity | null;
159
+ password: string;
160
+ hidden: boolean;
161
+ }
162
+ export interface NetworkResult {
163
+ uuid: string | null;
164
+ message: string | null;
165
+ }
166
+ export declare const WRONG_PASSWORD = "Wrong password, or none given";
167
+ export declare const SECURITY_LABELS: Record<WifiSecurity, string>;
168
+ export declare function needsPassword(security: WifiSecurity): boolean;
169
+ export declare function isInterfaceName(name: string): boolean;
170
+ export declare function isUuid(uuid: string): boolean;
171
+ export declare function isIpv4(address: string): boolean;
172
+ export declare function isIpv6(address: string): boolean;
173
+ export declare function cidrProblem(cidr: string): string | null;
174
+ export declare function splitList(text: string): string[];
175
+ export declare function passwordProblem(security: WifiSecurity, password: string, hotspot?: boolean): string | null;
176
+ export declare function settingsProblems(settings: NetworkSettings, creating: boolean): Partial<Record<keyof NetworkSettings, string>>;
177
+ export declare function settingsOf(connection: NetworkConnection): NetworkSettings | null;
178
+ export declare function defaultSettings(kind: EditableKind): NetworkSettings;
@@ -1,4 +1,5 @@
1
1
  import type { BtNodeModel } from './bt_nodes.ts';
2
+ import type { NetworkRequest, NetworkState } from './networking.ts';
2
3
  export type ImageTransport = 'auto' | 'raw' | 'compressed';
3
4
  export type GridStyle = 'map' | 'costmap';
4
5
  export interface TwistCommand {
@@ -192,7 +193,53 @@ export interface RosoutSubscribe {
192
193
  id: number;
193
194
  topic: string;
194
195
  }
195
- export type ClientMessage = TwistCommand | ImageSubscribe | GridSubscribe | TfSubscribe | PathSubscribe | TopicSubscribe | ServicesSubscribe | ServiceAction | LogsSubscribe | Unsubscribe | FrameAck | PosePublish | CommandRun | CommandStop | ArmSubscribe | ArmJog | RosPublish | RosCall | PluginRequest | PluginSubscribe | BehaviorTreeSubscribe | BehaviorTreeRecord | BehaviorTreePlaybackSubscribe | BehaviorTreePlaybackControl | BehaviorTreeFileSubscribe | BehaviorTreeFileSave | RosoutSubscribe;
196
+ export interface DiagnosticsSubscribe {
197
+ type: 'diagnostics.subscribe';
198
+ id: number;
199
+ topic: string;
200
+ }
201
+ export interface TerminalOpen {
202
+ type: 'terminal.open';
203
+ id: number;
204
+ terminal: string;
205
+ command: string;
206
+ folder: string;
207
+ cols: number;
208
+ rows: number;
209
+ started: number | null;
210
+ offset: number | null;
211
+ }
212
+ export interface TerminalInput {
213
+ type: 'terminal.input';
214
+ id: number;
215
+ data: string;
216
+ }
217
+ export interface TerminalResize {
218
+ type: 'terminal.resize';
219
+ id: number;
220
+ cols: number;
221
+ rows: number;
222
+ }
223
+ export interface TerminalAck {
224
+ type: 'terminal.ack';
225
+ id: number;
226
+ started: number;
227
+ offset: number;
228
+ }
229
+ export interface TerminalRestart {
230
+ type: 'terminal.restart';
231
+ id: number;
232
+ }
233
+ export interface NetworkSubscribe {
234
+ type: 'network.subscribe';
235
+ id: number;
236
+ }
237
+ export interface NetworkAction {
238
+ type: 'network.action';
239
+ id: number;
240
+ request: NetworkRequest;
241
+ }
242
+ export type ClientMessage = TwistCommand | ImageSubscribe | GridSubscribe | TfSubscribe | PathSubscribe | TopicSubscribe | ServicesSubscribe | ServiceAction | LogsSubscribe | Unsubscribe | FrameAck | PosePublish | CommandRun | CommandStop | ArmSubscribe | ArmJog | RosPublish | RosCall | PluginRequest | PluginSubscribe | BehaviorTreeSubscribe | BehaviorTreeRecord | BehaviorTreePlaybackSubscribe | BehaviorTreePlaybackControl | BehaviorTreeFileSubscribe | BehaviorTreeFileSave | RosoutSubscribe | DiagnosticsSubscribe | TerminalOpen | TerminalInput | TerminalResize | TerminalAck | TerminalRestart | NetworkSubscribe | NetworkAction;
196
243
  export interface Hello {
197
244
  type: 'hello';
198
245
  clientId: string;
@@ -429,7 +476,57 @@ export interface RosoutUpdate {
429
476
  skipped: number;
430
477
  nodes: string[] | null;
431
478
  }
432
- export type ServerMessage = Hello | CommandStates | CommandUpdate | StreamStatus | TfUpdate | PathUpdate | TopicMessage | ServicesUpdate | ServiceResult | LogsUpdate | ArmUpdate | Result | PluginData | BehaviorTreeInfo | BehaviorTreeUpdate | BehaviorTreeRecording | BehaviorTreePlaybackState | BehaviorTreeFile | BehaviorTreeModels | RosoutUpdate | PanelsChanged | ErrorMessage;
479
+ export interface DiagnosticEntry {
480
+ id: number;
481
+ name: string;
482
+ level: number;
483
+ message: string;
484
+ hardwareId: string;
485
+ values: {
486
+ key: string;
487
+ value: string;
488
+ }[];
489
+ stale: boolean;
490
+ updated: number;
491
+ since: number;
492
+ }
493
+ export interface DiagnosticChange {
494
+ seq: number;
495
+ time: number;
496
+ status: number;
497
+ level: number;
498
+ message: string;
499
+ }
500
+ export interface DiagnosticsUpdate {
501
+ type: 'diagnostics';
502
+ id: number;
503
+ reset: boolean;
504
+ started: number;
505
+ statuses: DiagnosticEntry[];
506
+ changes: DiagnosticChange[];
507
+ }
508
+ export interface TerminalOutput {
509
+ type: 'terminal.output';
510
+ id: number;
511
+ started: number;
512
+ offset: number;
513
+ reset: boolean;
514
+ data: string;
515
+ title: string | null;
516
+ }
517
+ export interface TerminalExit {
518
+ type: 'terminal.exit';
519
+ id: number;
520
+ started: number;
521
+ exitCode: number | null;
522
+ }
523
+ export interface NetworkUpdate extends NetworkState {
524
+ type: 'network';
525
+ id: number;
526
+ via: string | null;
527
+ canChange: boolean;
528
+ }
529
+ export type ServerMessage = Hello | CommandStates | CommandUpdate | StreamStatus | TfUpdate | PathUpdate | TopicMessage | ServicesUpdate | ServiceResult | LogsUpdate | ArmUpdate | Result | PluginData | BehaviorTreeInfo | BehaviorTreeUpdate | BehaviorTreeRecording | BehaviorTreePlaybackState | BehaviorTreeFile | BehaviorTreeModels | RosoutUpdate | DiagnosticsUpdate | TerminalOutput | TerminalExit | NetworkUpdate | PanelsChanged | ErrorMessage;
433
530
  export declare const FRAME_HEADER_BYTES = 11;
434
531
  export declare const IMAGE_FORMATS: readonly ['image/jpeg', 'image/png'];
435
532
  export interface GridInfo {
@@ -452,6 +549,10 @@ export declare const ARM_STATE_RATE = 10;
452
549
  export declare const BT_RATE = 10;
453
550
  export declare const ROSOUT_RATE = 10;
454
551
  export declare const ROSOUT_HISTORY = 10000;
552
+ export declare const DIAGNOSTICS_RATE = 4;
553
+ export declare const DIAGNOSTICS_CHANGES = 1000;
554
+ export declare const TERMINAL_SCROLLBACK = 2000;
555
+ export declare const TERMINAL_WINDOW: number;
455
556
  export declare const DASHBOARD_CLIENT_HEADER = "X-Dashboard-Client";
456
557
  export interface PluginInfo {
457
558
  name: string;
@@ -1 +1 @@
1
- import{n as e}from"./rolldown-runtime.js";import{t}from"./react.js";import{it as n,lt as r,u as i}from"./icons.js";import{t as a}from"./jsx-runtime.js";async function o(e,t,i){let a=await fetch(t,{method:e,headers:{"Content-Type":`application/json`,[r]:n.clientId??``},body:i===void 0?void 0:JSON.stringify(i)});if(!a.ok){let e=`${a.status} ${a.statusText}`;try{e=(await a.json()).error??e}catch{}throw Error(e)}return a.status===204?void 0:await a.json()}var s=e=>`/api/panels/${encodeURIComponent(e)}`;async function c(e){let t=await fetch(`/api/uploads`,{method:`POST`,body:e});if(!t.ok){let e=await t.json().catch(()=>null);throw Error(e?.error??`${t.status} ${t.statusText}`)}return await t.json()}function l(e){let t=e.trim();if(t.startsWith(`uploads/`))return`/api/uploads/${encodeURIComponent(t.slice(8))}`;let n=/^package:\/\/([^/]+)\/(.+)$/.exec(t);return n?`/api/packages/${encodeURIComponent(n[1])}/${n[2].split(`/`).map(encodeURIComponent).join(`/`)}`:t.startsWith(`/`)||t.startsWith(`~/`)?`/api/files?path=${encodeURIComponent(t)}`:null}var u={listPanels:()=>o(`GET`,`/api/panels`),getPanel:e=>o(`GET`,s(e)),createPanel:e=>o(`POST`,`/api/panels`,e),savePanel:e=>o(`PUT`,s(e.id),e),deletePanel:e=>o(`DELETE`,s(e)),listTopics:()=>o(`GET`,`/api/topics`),listPlugins:()=>o(`GET`,`/api/plugins`),listFiles:(e,t=`image`)=>o(`GET`,`/api/files/list?dir=${encodeURIComponent(e)}&kind=${t}`),uploadFile:async e=>`uploads/${(await c(e)).name}`},d=e(t(),1),f=e(a(),1);function p({title:e,onClose:t,children:n,wide:r=!1,resizable:a=!1}){return(0,d.useEffect)(()=>{let e=e=>{e.key===`Escape`&&t()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[t]),(0,f.jsx)(`div`,{className:`modal-backdrop`,onPointerDown:e=>e.target===e.currentTarget&&t(),children:(0,f.jsxs)(`div`,{className:`modal${r?` wide`:``}${a?` resizable`:``}`,role:`dialog`,"aria-modal":`true`,"aria-label":e,children:[(0,f.jsxs)(`header`,{className:`modal-header`,children:[(0,f.jsx)(`h2`,{children:e}),(0,f.jsx)(`button`,{type:`button`,className:`icon-button`,"aria-label":`Close`,onClick:t,children:(0,f.jsx)(i,{})})]}),n]})})}var m=1,h=(0,d.createContext)(null);function g(){let e=(0,d.useContext)(h);if(!e)throw Error(`useDialogs() outside of <DialogProvider>`);return e}function _({children:e}){let[t,n]=(0,d.useState)(null),r=(0,d.useMemo)(()=>({confirm:e=>new Promise(t=>n({id:m++,kind:`confirm`,resolve:t,...e})),prompt:e=>new Promise(t=>n({id:m++,kind:`prompt`,resolve:t,...e}))}),[]);return(0,f.jsxs)(h.Provider,{value:r,children:[e,t&&(0,f.jsx)(v,{request:t,onDone:()=>n(null)},t.id)]})}function v({request:e,onDone:t}){let[n,r]=(0,d.useState)(e.kind===`prompt`?e.initial??``:``),i=(0,d.useRef)(null);(0,d.useEffect)(()=>i.current?.select(),[]);let a=r=>{e.kind===`confirm`?e.resolve(r):e.resolve(r&&n.trim()?n.trim():null),t()};return(0,f.jsx)(p,{title:e.title,onClose:()=>a(!1),children:(0,f.jsxs)(`form`,{className:`modal-body`,onSubmit:e=>{e.preventDefault(),a(!0)},children:[e.kind===`confirm`?e.message&&(0,f.jsx)(`div`,{className:`dialog-message`,children:e.message}):(0,f.jsxs)(`label`,{className:`field`,children:[(0,f.jsx)(`span`,{className:`field-label`,children:e.label}),(0,f.jsx)(`input`,{ref:i,value:n,onChange:e=>r(e.target.value),autoFocus:!0})]}),(0,f.jsxs)(`div`,{className:`modal-actions`,children:[(0,f.jsx)(`button`,{type:`button`,className:`button`,onClick:()=>a(!1),children:`Cancel`}),(0,f.jsx)(`button`,{type:`submit`,className:`button ${e.kind===`confirm`&&e.danger?`danger`:`primary`}`,disabled:e.kind===`prompt`&&!n.trim(),autoFocus:e.kind===`confirm`,children:e.confirmLabel??`OK`})]})]})})}var y=5e3,b=[],x=1,S=new Set;function C(e){b=e,S.forEach(e=>e())}function w(e){C(b.filter(t=>t.id!==e))}function T(e,t=`info`,n){let r=x++;C([...b.filter(t=>t.message!==e),{id:r,message:e,kind:t,action:n}].slice(-4)),setTimeout(()=>w(r),y)}function E(e){return S.add(e),()=>S.delete(e)}function D(){let e=(0,d.useSyncExternalStore)(E,()=>b);return(0,f.jsx)(`div`,{className:`notifications`,role:`status`,"aria-live":`polite`,children:e.map(e=>(0,f.jsxs)(`div`,{className:`notification ${e.kind}`,children:[(0,f.jsx)(`span`,{children:e.message}),e.action&&(0,f.jsx)(`button`,{type:`button`,className:`link-button`,onClick:()=>{e.action?.run(),w(e.id)},children:e.action.label}),(0,f.jsx)(`button`,{type:`button`,className:`notification-close`,"aria-label":`Dismiss`,onClick:()=>w(e.id),children:`×`})]},e.id))})}function O(e){return e}function k(e){return e}var A=34,j=.08;function M(e){let t=Math.abs(e);return t<j?0:Math.sign(e)*(t-j)/.92}function N({axes:e,onMove:t,disabled:n,label:r}){let i=(0,d.useRef)(null),a=(0,d.useRef)(null),[o,s]=(0,d.useState)({x:0,y:0}),[c,l]=(0,d.useState)(!1),u=(0,d.useRef)(t);u.current=t;let p=(e,t)=>{s({x:e,y:t}),u.current(M(e),M(t))},m=t=>{let n=i.current.getBoundingClientRect(),r=n.width*A/100,a=e===`y`?0:(t.clientX-(n.left+n.width/2))/r,o=e===`x`?0:-(t.clientY-(n.top+n.height/2))/r,s=Math.hypot(a,o);s>1&&(a/=s,o/=s),p(a,o)},h=e=>{a.current===null||e&&e.pointerId!==a.current||(a.current=null,l(!1),p(0,0))},g=(0,d.useRef)(h);return g.current=h,(0,d.useEffect)(()=>{let e=()=>document.hidden&&g.current();return document.addEventListener(`visibilitychange`,e),()=>document.removeEventListener(`visibilitychange`,e)},[]),(0,d.useEffect)(()=>{n&&g.current()},[n]),(0,f.jsxs)(`div`,{className:`joystick-slot`,children:[(0,f.jsxs)(`div`,{ref:i,className:`joystick${e===`x`?` horizontal`:e===`y`?` vertical`:``}${c?` active`:``}${n?` disabled`:``}`,onPointerDown:e=>{n||a.current!==null||e.button!==0||(a.current=e.pointerId,l(!0),e.currentTarget.setPointerCapture(e.pointerId),m(e))},onPointerMove:e=>e.pointerId===a.current&&m(e),onPointerUp:h,onPointerCancel:h,onLostPointerCapture:h,children:[(0,f.jsx)(`div`,{className:`joystick-track`}),(0,f.jsx)(`div`,{className:`joystick-knob`,style:{left:`${50+o.x*A}%`,top:`${50-o.y*A}%`}})]}),(0,f.jsx)(`span`,{className:`joystick-label`,children:r})]})}export{T as a,g as c,D as i,u as l,k as n,_ as o,O as r,p as s,N as t,l as u};
1
+ import{n as e}from"./rolldown-runtime.js";import{t}from"./react.js";import{Ht as n,Lt as r}from"./icons.js";import{t as i}from"./jsx-runtime.js";var a=class extends Error{status;constructor(e,t){super(t),this.status=e}};async function o(e,t,i){let o=await fetch(t,{method:e,headers:{"Content-Type":`application/json`,[n]:r.clientId??``},body:i===void 0?void 0:JSON.stringify(i)});if(!o.ok){let e=`${o.status} ${o.statusText}`;try{e=(await o.json()).error??e}catch{}throw new a(o.status,e)}return o.status===204?void 0:await o.json()}var s=e=>`/api/panels/${encodeURIComponent(e)}`;async function c(e){let t=await fetch(`/api/uploads`,{method:`POST`,body:e});if(!t.ok){let e=await t.json().catch(()=>null);throw Error(e?.error??`${t.status} ${t.statusText}`)}return await t.json()}function l(e){let t=e.trim();if(t.startsWith(`uploads/`))return`/api/uploads/${encodeURIComponent(t.slice(8))}`;let n=/^package:\/\/([^/]+)\/(.+)$/.exec(t);return n?`/api/packages/${encodeURIComponent(n[1])}/${n[2].split(`/`).map(encodeURIComponent).join(`/`)}`:t.startsWith(`/`)||t.startsWith(`~/`)?`/api/files?path=${encodeURIComponent(t)}`:null}var u={listPanels:()=>o(`GET`,`/api/panels`),getPanel:e=>o(`GET`,s(e)),createPanel:e=>o(`POST`,`/api/panels`,e),savePanel:e=>o(`PUT`,s(e.id),e),deletePanel:e=>o(`DELETE`,s(e)),listTopics:()=>o(`GET`,`/api/topics`),listPlugins:()=>o(`GET`,`/api/plugins`),listFiles:(e,t=`image`)=>o(`GET`,`/api/files/list?dir=${encodeURIComponent(e)}&kind=${t}`),uploadFile:async e=>`uploads/${(await c(e)).name}`};function d(e,t={}){let n=new URLSearchParams;for(let[e,r]of Object.entries(t))for(let t of r==null?[]:[r].flat())n.append(e,t);let r=n.toString();return`/api/fs/${e}${r?`?${r}`:``}`}var f={places:()=>o(`GET`,d(`places`)),list:(e,t)=>o(`GET`,d(`list`,{path:e,known:t})),details:e=>o(`GET`,d(`details`,{path:e})),disks:()=>o(`GET`,d(`disks`)),analyze:e=>o(`GET`,d(`analysis`,{path:e})),readText:(e,t)=>o(`GET`,d(`text`,{path:e,stamp:t})),saveText:(e,t,n,r=!1)=>o(`PUT`,d(`text`),{path:e,text:t,base:n,create:r}),operate:e=>o(`POST`,d(`op`),e),downloadUrl:e=>d(`download`,{path:e}),viewUrl:(e,t)=>d(`view`,{path:e,v:t}),upload(e,t,i,a,o){let s=new XMLHttpRequest;return{result:new Promise((c,l)=>{s.open(`POST`,d(`upload`,{path:e,name:t,conflict:a})),s.setRequestHeader(n,r.clientId??``),s.upload.onprogress=e=>o(e.loaded),s.onload=()=>{let e=null;try{e=JSON.parse(s.responseText)}catch{}s.status>=200&&s.status<300&&e?c(e):l(Error(e?.error??`${s.status} ${s.statusText}`))},s.onerror=()=>l(Error(`Cannot reach the robot`)),s.onabort=()=>l(new DOMException(`Cancelled`,`AbortError`)),s.send(i)}),abort:()=>s.abort()}}},p=e(t(),1),m=e(i(),1),h=5e3,g=[],_=1,v=new Set;function y(e){g=e,v.forEach(e=>e())}function b(e){y(g.filter(t=>t.id!==e))}function x(e,t=`info`,n){let r=_++;y([...g.filter(t=>t.message!==e),{id:r,message:e,kind:t,action:n}].slice(-4)),setTimeout(()=>b(r),h)}function S(e){return v.add(e),()=>v.delete(e)}function C(){let e=(0,p.useSyncExternalStore)(S,()=>g);return(0,m.jsx)(`div`,{className:`notifications`,role:`status`,"aria-live":`polite`,children:e.map(e=>(0,m.jsxs)(`div`,{className:`notification ${e.kind}`,children:[(0,m.jsx)(`span`,{children:e.message}),e.action&&(0,m.jsx)(`button`,{type:`button`,className:`link-button`,onClick:()=>{e.action?.run(),b(e.id)},children:e.action.label}),(0,m.jsx)(`button`,{type:`button`,className:`notification-close`,"aria-label":`Dismiss`,onClick:()=>b(e.id),children:`×`})]},e.id))})}function w(e){return e}function T(e){return e}var E=34,D=.08;function O(e){let t=Math.abs(e);return t<D?0:Math.sign(e)*(t-D)/.92}function k({axes:e,onMove:t,disabled:n,label:r}){let i=(0,p.useRef)(null),a=(0,p.useRef)(null),[o,s]=(0,p.useState)({x:0,y:0}),[c,l]=(0,p.useState)(!1),u=(0,p.useRef)(t);u.current=t;let d=(e,t)=>{s({x:e,y:t}),u.current(O(e),O(t))},f=t=>{let n=i.current.getBoundingClientRect(),r=n.width*E/100,a=e===`y`?0:(t.clientX-(n.left+n.width/2))/r,o=e===`x`?0:-(t.clientY-(n.top+n.height/2))/r,s=Math.hypot(a,o);s>1&&(a/=s,o/=s),d(a,o)},h=e=>{a.current===null||e&&e.pointerId!==a.current||(a.current=null,l(!1),d(0,0))},g=(0,p.useRef)(h);return g.current=h,(0,p.useEffect)(()=>{let e=()=>document.hidden&&g.current();return document.addEventListener(`visibilitychange`,e),()=>document.removeEventListener(`visibilitychange`,e)},[]),(0,p.useEffect)(()=>{n&&g.current()},[n]),(0,m.jsxs)(`div`,{className:`joystick-slot`,children:[(0,m.jsxs)(`div`,{ref:i,className:`joystick${e===`x`?` horizontal`:e===`y`?` vertical`:``}${c?` active`:``}${n?` disabled`:``}`,onPointerDown:e=>{n||a.current!==null||e.button!==0||(a.current=e.pointerId,l(!0),e.currentTarget.setPointerCapture(e.pointerId),f(e))},onPointerMove:e=>e.pointerId===a.current&&f(e),onPointerUp:h,onPointerCancel:h,onLostPointerCapture:h,children:[(0,m.jsx)(`div`,{className:`joystick-track`}),(0,m.jsx)(`div`,{className:`joystick-knob`,style:{left:`${50+o.x*E}%`,top:`${50-o.y*E}%`}})]}),(0,m.jsx)(`span`,{className:`joystick-label`,children:r})]})}export{x as a,f as c,C as i,l,T as n,a as o,w as r,u as s,k as t};