@plures/praxis 0.2.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 (263) hide show
  1. package/FRAMEWORK.md +420 -0
  2. package/LICENSE +21 -0
  3. package/README.md +1310 -0
  4. package/dist/adapters/cli.d.ts +43 -0
  5. package/dist/adapters/cli.d.ts.map +1 -0
  6. package/dist/adapters/cli.js +126 -0
  7. package/dist/adapters/cli.js.map +1 -0
  8. package/dist/cli/commands/auth.d.ts +26 -0
  9. package/dist/cli/commands/auth.d.ts.map +1 -0
  10. package/dist/cli/commands/auth.js +233 -0
  11. package/dist/cli/commands/auth.js.map +1 -0
  12. package/dist/cli/commands/cloud.d.ts +27 -0
  13. package/dist/cli/commands/cloud.d.ts.map +1 -0
  14. package/dist/cli/commands/cloud.js +232 -0
  15. package/dist/cli/commands/cloud.js.map +1 -0
  16. package/dist/cli/commands/generate.d.ts +25 -0
  17. package/dist/cli/commands/generate.d.ts.map +1 -0
  18. package/dist/cli/commands/generate.js +168 -0
  19. package/dist/cli/commands/generate.js.map +1 -0
  20. package/dist/cli/index.d.ts +8 -0
  21. package/dist/cli/index.d.ts.map +1 -0
  22. package/dist/cli/index.js +179 -0
  23. package/dist/cli/index.js.map +1 -0
  24. package/dist/cloud/auth.d.ts +51 -0
  25. package/dist/cloud/auth.d.ts.map +1 -0
  26. package/dist/cloud/auth.js +194 -0
  27. package/dist/cloud/auth.js.map +1 -0
  28. package/dist/cloud/billing.d.ts +184 -0
  29. package/dist/cloud/billing.d.ts.map +1 -0
  30. package/dist/cloud/billing.js +179 -0
  31. package/dist/cloud/billing.js.map +1 -0
  32. package/dist/cloud/client.d.ts +39 -0
  33. package/dist/cloud/client.d.ts.map +1 -0
  34. package/dist/cloud/client.js +176 -0
  35. package/dist/cloud/client.js.map +1 -0
  36. package/dist/cloud/index.d.ts +44 -0
  37. package/dist/cloud/index.d.ts.map +1 -0
  38. package/dist/cloud/index.js +44 -0
  39. package/dist/cloud/index.js.map +1 -0
  40. package/dist/cloud/marketplace.d.ts +166 -0
  41. package/dist/cloud/marketplace.d.ts.map +1 -0
  42. package/dist/cloud/marketplace.js +159 -0
  43. package/dist/cloud/marketplace.js.map +1 -0
  44. package/dist/cloud/provisioning.d.ts +110 -0
  45. package/dist/cloud/provisioning.d.ts.map +1 -0
  46. package/dist/cloud/provisioning.js +148 -0
  47. package/dist/cloud/provisioning.js.map +1 -0
  48. package/dist/cloud/relay/endpoints.d.ts +62 -0
  49. package/dist/cloud/relay/endpoints.d.ts.map +1 -0
  50. package/dist/cloud/relay/endpoints.js +217 -0
  51. package/dist/cloud/relay/endpoints.js.map +1 -0
  52. package/dist/cloud/relay/health/index.d.ts +5 -0
  53. package/dist/cloud/relay/health/index.d.ts.map +1 -0
  54. package/dist/cloud/relay/health/index.js +9 -0
  55. package/dist/cloud/relay/health/index.js.map +1 -0
  56. package/dist/cloud/relay/stats/index.d.ts +5 -0
  57. package/dist/cloud/relay/stats/index.d.ts.map +1 -0
  58. package/dist/cloud/relay/stats/index.js +9 -0
  59. package/dist/cloud/relay/stats/index.js.map +1 -0
  60. package/dist/cloud/relay/sync/index.d.ts +5 -0
  61. package/dist/cloud/relay/sync/index.d.ts.map +1 -0
  62. package/dist/cloud/relay/sync/index.js +9 -0
  63. package/dist/cloud/relay/sync/index.js.map +1 -0
  64. package/dist/cloud/relay/usage/index.d.ts +5 -0
  65. package/dist/cloud/relay/usage/index.d.ts.map +1 -0
  66. package/dist/cloud/relay/usage/index.js +9 -0
  67. package/dist/cloud/relay/usage/index.js.map +1 -0
  68. package/dist/cloud/sponsors.d.ts +81 -0
  69. package/dist/cloud/sponsors.d.ts.map +1 -0
  70. package/dist/cloud/sponsors.js +130 -0
  71. package/dist/cloud/sponsors.js.map +1 -0
  72. package/dist/cloud/types.d.ts +169 -0
  73. package/dist/cloud/types.d.ts.map +1 -0
  74. package/dist/cloud/types.js +7 -0
  75. package/dist/cloud/types.js.map +1 -0
  76. package/dist/components/index.d.ts +43 -0
  77. package/dist/components/index.d.ts.map +1 -0
  78. package/dist/components/index.js +17 -0
  79. package/dist/components/index.js.map +1 -0
  80. package/dist/core/actors.d.ts +95 -0
  81. package/dist/core/actors.d.ts.map +1 -0
  82. package/dist/core/actors.js +158 -0
  83. package/dist/core/actors.js.map +1 -0
  84. package/dist/core/component/generator.d.ts +122 -0
  85. package/dist/core/component/generator.d.ts.map +1 -0
  86. package/dist/core/component/generator.js +307 -0
  87. package/dist/core/component/generator.js.map +1 -0
  88. package/dist/core/engine.d.ts +92 -0
  89. package/dist/core/engine.d.ts.map +1 -0
  90. package/dist/core/engine.js +199 -0
  91. package/dist/core/engine.js.map +1 -0
  92. package/dist/core/introspection.d.ts +141 -0
  93. package/dist/core/introspection.d.ts.map +1 -0
  94. package/dist/core/introspection.js +208 -0
  95. package/dist/core/introspection.js.map +1 -0
  96. package/dist/core/logic/generator.d.ts +76 -0
  97. package/dist/core/logic/generator.d.ts.map +1 -0
  98. package/dist/core/logic/generator.js +339 -0
  99. package/dist/core/logic/generator.js.map +1 -0
  100. package/dist/core/pluresdb/generator.d.ts +58 -0
  101. package/dist/core/pluresdb/generator.d.ts.map +1 -0
  102. package/dist/core/pluresdb/generator.js +162 -0
  103. package/dist/core/pluresdb/generator.js.map +1 -0
  104. package/dist/core/protocol.d.ts +121 -0
  105. package/dist/core/protocol.d.ts.map +1 -0
  106. package/dist/core/protocol.js +46 -0
  107. package/dist/core/protocol.js.map +1 -0
  108. package/dist/core/rules.d.ts +120 -0
  109. package/dist/core/rules.d.ts.map +1 -0
  110. package/dist/core/rules.js +81 -0
  111. package/dist/core/rules.js.map +1 -0
  112. package/dist/core/schema/loader.d.ts +47 -0
  113. package/dist/core/schema/loader.d.ts.map +1 -0
  114. package/dist/core/schema/loader.js +189 -0
  115. package/dist/core/schema/loader.js.map +1 -0
  116. package/dist/core/schema/normalize.d.ts +72 -0
  117. package/dist/core/schema/normalize.d.ts.map +1 -0
  118. package/dist/core/schema/normalize.js +190 -0
  119. package/dist/core/schema/normalize.js.map +1 -0
  120. package/dist/core/schema/types.d.ts +370 -0
  121. package/dist/core/schema/types.d.ts.map +1 -0
  122. package/dist/core/schema/types.js +161 -0
  123. package/dist/core/schema/types.js.map +1 -0
  124. package/dist/dsl/index.d.ts +152 -0
  125. package/dist/dsl/index.d.ts.map +1 -0
  126. package/dist/dsl/index.js +132 -0
  127. package/dist/dsl/index.js.map +1 -0
  128. package/dist/dsl.d.ts +124 -0
  129. package/dist/dsl.d.ts.map +1 -0
  130. package/dist/dsl.js +130 -0
  131. package/dist/dsl.js.map +1 -0
  132. package/dist/examples/advanced-todo/index.d.ts +55 -0
  133. package/dist/examples/advanced-todo/index.d.ts.map +1 -0
  134. package/dist/examples/advanced-todo/index.js +222 -0
  135. package/dist/examples/advanced-todo/index.js.map +1 -0
  136. package/dist/examples/auth-basic/index.d.ts +17 -0
  137. package/dist/examples/auth-basic/index.d.ts.map +1 -0
  138. package/dist/examples/auth-basic/index.js +122 -0
  139. package/dist/examples/auth-basic/index.js.map +1 -0
  140. package/dist/examples/cart/index.d.ts +19 -0
  141. package/dist/examples/cart/index.d.ts.map +1 -0
  142. package/dist/examples/cart/index.js +202 -0
  143. package/dist/examples/cart/index.js.map +1 -0
  144. package/dist/examples/hero-ecommerce/index.d.ts +39 -0
  145. package/dist/examples/hero-ecommerce/index.d.ts.map +1 -0
  146. package/dist/examples/hero-ecommerce/index.js +506 -0
  147. package/dist/examples/hero-ecommerce/index.js.map +1 -0
  148. package/dist/examples/svelte-counter/index.d.ts +31 -0
  149. package/dist/examples/svelte-counter/index.d.ts.map +1 -0
  150. package/dist/examples/svelte-counter/index.js +123 -0
  151. package/dist/examples/svelte-counter/index.js.map +1 -0
  152. package/dist/flows.d.ts +125 -0
  153. package/dist/flows.d.ts.map +1 -0
  154. package/dist/flows.js +160 -0
  155. package/dist/flows.js.map +1 -0
  156. package/dist/index.d.ts +67 -0
  157. package/dist/index.d.ts.map +1 -0
  158. package/dist/index.js +59 -0
  159. package/dist/index.js.map +1 -0
  160. package/dist/integrations/pluresdb.d.ts +56 -0
  161. package/dist/integrations/pluresdb.d.ts.map +1 -0
  162. package/dist/integrations/pluresdb.js +46 -0
  163. package/dist/integrations/pluresdb.js.map +1 -0
  164. package/dist/integrations/svelte.d.ts +306 -0
  165. package/dist/integrations/svelte.d.ts.map +1 -0
  166. package/dist/integrations/svelte.js +447 -0
  167. package/dist/integrations/svelte.js.map +1 -0
  168. package/dist/registry.d.ts +94 -0
  169. package/dist/registry.d.ts.map +1 -0
  170. package/dist/registry.js +181 -0
  171. package/dist/registry.js.map +1 -0
  172. package/dist/runtime/terminal-adapter.d.ts +105 -0
  173. package/dist/runtime/terminal-adapter.d.ts.map +1 -0
  174. package/dist/runtime/terminal-adapter.js +113 -0
  175. package/dist/runtime/terminal-adapter.js.map +1 -0
  176. package/dist/step.d.ts +34 -0
  177. package/dist/step.d.ts.map +1 -0
  178. package/dist/step.js +111 -0
  179. package/dist/step.js.map +1 -0
  180. package/dist/types.d.ts +63 -0
  181. package/dist/types.d.ts.map +1 -0
  182. package/dist/types.js +6 -0
  183. package/dist/types.js.map +1 -0
  184. package/docs/MONETIZATION.md +394 -0
  185. package/docs/TERMINAL_NODE.md +588 -0
  186. package/docs/guides/canvas.md +389 -0
  187. package/docs/guides/getting-started.md +347 -0
  188. package/docs/guides/history-state-pattern.md +618 -0
  189. package/docs/guides/orchestration.md +617 -0
  190. package/docs/guides/parallel-state-pattern.md +767 -0
  191. package/docs/guides/svelte-integration.md +691 -0
  192. package/package.json +96 -0
  193. package/src/__tests__/actors.test.ts +270 -0
  194. package/src/__tests__/billing.test.ts +175 -0
  195. package/src/__tests__/cloud.test.ts +247 -0
  196. package/src/__tests__/dsl.test.ts +154 -0
  197. package/src/__tests__/edge-cases.test.ts +475 -0
  198. package/src/__tests__/engine.test.ts +137 -0
  199. package/src/__tests__/generators.test.ts +270 -0
  200. package/src/__tests__/introspection.test.ts +321 -0
  201. package/src/__tests__/protocol.test.ts +40 -0
  202. package/src/__tests__/provisioning.test.ts +162 -0
  203. package/src/__tests__/schema.test.ts +241 -0
  204. package/src/__tests__/svelte-integration.test.ts +431 -0
  205. package/src/__tests__/terminal-node.test.ts +352 -0
  206. package/src/adapters/cli.ts +175 -0
  207. package/src/cli/commands/auth.ts +271 -0
  208. package/src/cli/commands/cloud.ts +281 -0
  209. package/src/cli/commands/generate.ts +225 -0
  210. package/src/cli/index.ts +190 -0
  211. package/src/cloud/README.md +383 -0
  212. package/src/cloud/auth.ts +245 -0
  213. package/src/cloud/billing.ts +336 -0
  214. package/src/cloud/client.ts +221 -0
  215. package/src/cloud/index.ts +121 -0
  216. package/src/cloud/marketplace.ts +303 -0
  217. package/src/cloud/provisioning.ts +254 -0
  218. package/src/cloud/relay/endpoints.ts +307 -0
  219. package/src/cloud/relay/health/function.json +17 -0
  220. package/src/cloud/relay/health/index.ts +10 -0
  221. package/src/cloud/relay/host.json +15 -0
  222. package/src/cloud/relay/local.settings.json +8 -0
  223. package/src/cloud/relay/stats/function.json +17 -0
  224. package/src/cloud/relay/stats/index.ts +10 -0
  225. package/src/cloud/relay/sync/function.json +17 -0
  226. package/src/cloud/relay/sync/index.ts +10 -0
  227. package/src/cloud/relay/usage/function.json +17 -0
  228. package/src/cloud/relay/usage/index.ts +10 -0
  229. package/src/cloud/sponsors.ts +213 -0
  230. package/src/cloud/types.ts +198 -0
  231. package/src/components/README.md +125 -0
  232. package/src/components/TerminalNode.svelte +457 -0
  233. package/src/components/index.ts +46 -0
  234. package/src/core/actors.ts +205 -0
  235. package/src/core/component/generator.ts +432 -0
  236. package/src/core/engine.ts +243 -0
  237. package/src/core/introspection.ts +329 -0
  238. package/src/core/logic/generator.ts +420 -0
  239. package/src/core/pluresdb/generator.ts +229 -0
  240. package/src/core/protocol.ts +132 -0
  241. package/src/core/rules.ts +167 -0
  242. package/src/core/schema/loader.ts +247 -0
  243. package/src/core/schema/normalize.ts +322 -0
  244. package/src/core/schema/types.ts +557 -0
  245. package/src/dsl/index.ts +218 -0
  246. package/src/dsl.ts +214 -0
  247. package/src/examples/advanced-todo/App.svelte +506 -0
  248. package/src/examples/advanced-todo/README.md +371 -0
  249. package/src/examples/advanced-todo/index.ts +309 -0
  250. package/src/examples/auth-basic/index.ts +163 -0
  251. package/src/examples/cart/index.ts +259 -0
  252. package/src/examples/hero-ecommerce/index.ts +657 -0
  253. package/src/examples/svelte-counter/index.ts +168 -0
  254. package/src/flows.ts +268 -0
  255. package/src/index.ts +154 -0
  256. package/src/integrations/pluresdb.ts +93 -0
  257. package/src/integrations/svelte.ts +617 -0
  258. package/src/registry.ts +223 -0
  259. package/src/runtime/terminal-adapter.ts +175 -0
  260. package/src/step.ts +151 -0
  261. package/src/types.ts +70 -0
  262. package/templates/basic-app/README.md +147 -0
  263. package/templates/fullstack-app/README.md +279 -0
@@ -0,0 +1,588 @@
1
+ # Terminal Node Documentation
2
+
3
+ ## Overview
4
+
5
+ The Terminal Node is a new node type in Praxis that enables terminal/command execution capabilities within the Praxis framework. It provides a foundation for integrating command-line interfaces, scripting engines, and interactive shells into Praxis applications.
6
+
7
+ ## Features
8
+
9
+ - **Flexible Input Modes**: Support for text-based and widget-based input
10
+ - **Command History**: Automatic tracking of executed commands
11
+ - **PluresDB Integration**: Reactive state synchronization (ready for implementation)
12
+ - **RuneBook Integration**: Prepared for integration with the RuneBook execution model
13
+ - **YAML/JSON Schema Support**: Define terminal nodes declaratively
14
+ - **TypeScript Support**: Full type definitions for type-safe development
15
+
16
+ ## Installation
17
+
18
+ Terminal Node is part of the core Praxis package:
19
+
20
+ ```bash
21
+ npm install @plures/praxis
22
+ ```
23
+
24
+ ## Schema Definition
25
+
26
+ ### TypeScript
27
+
28
+ ```typescript
29
+ import type { PraxisSchema, NodeDefinition, TerminalNodeProps } from '@plures/praxis';
30
+
31
+ const schema: PraxisSchema = {
32
+ version: '1.0.0',
33
+ name: 'MyApp',
34
+ orchestration: {
35
+ type: 'custom',
36
+ nodes: [
37
+ {
38
+ id: 'terminal-1',
39
+ type: 'terminal',
40
+ x: 100,
41
+ y: 100,
42
+ props: {
43
+ inputMode: 'text',
44
+ history: [],
45
+ lastOutput: null,
46
+ },
47
+ bindings: {
48
+ input: '/terminal/input',
49
+ output: '/terminal/output',
50
+ },
51
+ },
52
+ ],
53
+ },
54
+ };
55
+ ```
56
+
57
+ ### YAML
58
+
59
+ ```yaml
60
+ version: "1.0.0"
61
+ name: "MyApp"
62
+ orchestration:
63
+ type: custom
64
+ nodes:
65
+ - id: terminal-1
66
+ type: terminal
67
+ x: 100
68
+ y: 100
69
+ props:
70
+ inputMode: text
71
+ history: []
72
+ lastOutput: null
73
+ bindings:
74
+ input: /terminal/input
75
+ output: /terminal/output
76
+ ```
77
+
78
+ ### JSON
79
+
80
+ ```json
81
+ {
82
+ "version": "1.0.0",
83
+ "name": "MyApp",
84
+ "orchestration": {
85
+ "type": "custom",
86
+ "nodes": [
87
+ {
88
+ "id": "terminal-1",
89
+ "type": "terminal",
90
+ "x": 100,
91
+ "y": 100,
92
+ "props": {
93
+ "inputMode": "text",
94
+ "history": [],
95
+ "lastOutput": null
96
+ },
97
+ "bindings": {
98
+ "input": "/terminal/input",
99
+ "output": "/terminal/output"
100
+ }
101
+ }
102
+ ]
103
+ }
104
+ }
105
+ ```
106
+
107
+ ## Runtime Usage
108
+
109
+ ### Creating a Terminal Adapter
110
+
111
+ ```typescript
112
+ import { createTerminalAdapter } from '@plures/praxis';
113
+
114
+ const terminal = createTerminalAdapter({
115
+ nodeId: 'my-terminal',
116
+ props: {
117
+ inputMode: 'text',
118
+ history: [],
119
+ lastOutput: null,
120
+ },
121
+ inputPath: '/terminal/input',
122
+ outputPath: '/terminal/output',
123
+ });
124
+ ```
125
+
126
+ ### Executing Commands
127
+
128
+ ```typescript
129
+ // Execute a command
130
+ const result = await terminal.executeCommand('echo "Hello World"');
131
+
132
+ console.log(result.command); // 'echo "Hello World"'
133
+ console.log(result.output); // Command output (currently stubbed)
134
+ console.log(result.exitCode); // 0 for success
135
+ console.log(result.timestamp); // Execution timestamp
136
+ ```
137
+
138
+ ### Managing Command History
139
+
140
+ ```typescript
141
+ // Get command history
142
+ const history = terminal.getHistory();
143
+ console.log(history); // ['echo "Hello World"', ...]
144
+
145
+ // Clear history
146
+ terminal.clearHistory();
147
+ ```
148
+
149
+ ### Updating Terminal Properties
150
+
151
+ ```typescript
152
+ // Update input mode
153
+ terminal.updateProps({
154
+ inputMode: 'widget',
155
+ });
156
+
157
+ // Get current state
158
+ const state = terminal.getState();
159
+ console.log(state.inputMode); // 'widget'
160
+ ```
161
+
162
+ ### Convenience Function
163
+
164
+ ```typescript
165
+ import { runTerminalCommand } from '@plures/praxis';
166
+
167
+ // Quick command execution
168
+ const result = await runTerminalCommand('temp-terminal', 'ls -la');
169
+ console.log(result.output);
170
+ ```
171
+
172
+ ## Svelte Component
173
+
174
+ ### TerminalNode.svelte
175
+
176
+ The `TerminalNode` Svelte component provides a visual terminal interface for canvas-based applications.
177
+
178
+ **Import:**
179
+
180
+ ```typescript
181
+ // Import the component directly from the .svelte file
182
+ import TerminalNode from '@plures/praxis/components/TerminalNode.svelte';
183
+ // Or use the package path if your bundler supports svelte exports
184
+ // import { TerminalNode } from '@plures/praxis/components';
185
+ ```
186
+
187
+ **Basic Usage:**
188
+
189
+ ```svelte
190
+ <script>
191
+ import TerminalNode from '@plures/praxis/components/TerminalNode.svelte';
192
+ import { createTerminalAdapter } from '@plures/praxis';
193
+
194
+ const terminal = createTerminalAdapter({
195
+ nodeId: 'my-terminal',
196
+ });
197
+ </script>
198
+
199
+ <TerminalNode adapter={terminal} x={100} y={100} />
200
+ ```
201
+
202
+ **Props:**
203
+
204
+ | Prop | Type | Default | Description |
205
+ |------|------|---------|-------------|
206
+ | `adapter` | `TerminalAdapter` | required | Terminal adapter instance |
207
+ | `x` | `number` | `0` | X position on canvas |
208
+ | `y` | `number` | `0` | Y position on canvas |
209
+ | `width` | `number` | `600` | Component width in pixels |
210
+ | `height` | `number` | `400` | Component height in pixels |
211
+ | `draggable` | `boolean` | `true` | Enable drag to move |
212
+ | `resizable` | `boolean` | `true` | Enable resize handle |
213
+ | `showContextMenu` | `boolean` | `false` | Show context menu |
214
+
215
+ **Features:**
216
+
217
+ - **Drag and Drop**: Click and drag the title bar to reposition
218
+ - **Resize**: Drag the bottom-right corner to resize
219
+ - **Context Menu**: Right-click for operations (clear, copy)
220
+ - **Keyboard Shortcuts**: Press Enter to execute commands
221
+ - **Command History**: Tracks all executed commands
222
+ - **Dark Theme**: VS Code-inspired dark color scheme
223
+ - **Input Modes**: Supports both text and widget input modes
224
+
225
+ **Complete Example:**
226
+
227
+ ```svelte
228
+ <script lang="ts">
229
+ import TerminalNode from '@plures/praxis/components/TerminalNode.svelte';
230
+ import { createTerminalAdapter } from '@plures/praxis';
231
+
232
+ // Create multiple terminals
233
+ const terminals = [
234
+ {
235
+ id: 'term-1',
236
+ adapter: createTerminalAdapter({
237
+ nodeId: 'terminal-1',
238
+ props: {
239
+ inputMode: 'text',
240
+ history: [],
241
+ lastOutput: null,
242
+ },
243
+ }),
244
+ x: 50,
245
+ y: 50,
246
+ },
247
+ {
248
+ id: 'term-2',
249
+ adapter: createTerminalAdapter({
250
+ nodeId: 'terminal-2',
251
+ props: {
252
+ inputMode: 'widget',
253
+ history: [],
254
+ lastOutput: null,
255
+ },
256
+ }),
257
+ x: 700,
258
+ y: 50,
259
+ },
260
+ ];
261
+ </script>
262
+
263
+ <div class="canvas">
264
+ {#each terminals as terminal (terminal.id)}
265
+ <TerminalNode
266
+ adapter={terminal.adapter}
267
+ x={terminal.x}
268
+ y={terminal.y}
269
+ width={600}
270
+ height={400}
271
+ draggable={true}
272
+ resizable={true}
273
+ />
274
+ {/each}
275
+ </div>
276
+
277
+ <style>
278
+ .canvas {
279
+ position: relative;
280
+ width: 100%;
281
+ height: 100vh;
282
+ background: #1a1a1a;
283
+ }
284
+ </style>
285
+ ```
286
+
287
+ See [examples/terminal-canvas/](../examples/terminal-canvas/) for a complete working example with toolbar and multiple terminals.
288
+
289
+ ## API Reference
290
+
291
+ ### TerminalNodeProps
292
+
293
+ Defines the properties of a terminal node.
294
+
295
+ ```typescript
296
+ interface TerminalNodeProps {
297
+ /** Input mode: text input or widget-based */
298
+ inputMode: 'text' | 'widget';
299
+ /** Command history */
300
+ history: string[];
301
+ /** Last command output */
302
+ lastOutput: string | null;
303
+ }
304
+ ```
305
+
306
+ ### NodeBindings
307
+
308
+ Defines PluresDB path bindings for reactive state management.
309
+
310
+ ```typescript
311
+ interface NodeBindings {
312
+ /** Output binding to pluresdb path */
313
+ output?: string;
314
+ /** Input binding to pluresdb path */
315
+ input?: string;
316
+ /** Additional custom bindings */
317
+ [key: string]: string | undefined;
318
+ }
319
+ ```
320
+
321
+ ### NodeDefinition
322
+
323
+ Extended to support terminal nodes and other orchestration node types.
324
+
325
+ ```typescript
326
+ interface NodeDefinition {
327
+ /** Node identifier */
328
+ id: string;
329
+ /** Node type */
330
+ type: string;
331
+ /** Node configuration */
332
+ config: Record<string, unknown>;
333
+ /** Node position (x, y coordinates for canvas) */
334
+ x?: number;
335
+ y?: number;
336
+ /** Node props (type-specific properties) */
337
+ props?: Record<string, unknown>;
338
+ /** Node bindings (connections to pluresdb paths) */
339
+ bindings?: NodeBindings;
340
+ }
341
+ ```
342
+
343
+ ### TerminalAdapter
344
+
345
+ The main class for managing terminal node runtime behavior.
346
+
347
+ ```typescript
348
+ class TerminalAdapter {
349
+ constructor(options: TerminalAdapterOptions);
350
+
351
+ /** Execute a terminal command */
352
+ executeCommand(command: string): Promise<TerminalExecutionResult>;
353
+
354
+ /** Get current terminal state */
355
+ getState(): Readonly<TerminalNodeState>;
356
+
357
+ /** Update terminal props */
358
+ updateProps(props: Partial<TerminalNodeProps>): void;
359
+
360
+ /** Clear command history */
361
+ clearHistory(): void;
362
+
363
+ /** Get command history */
364
+ getHistory(): ReadonlyArray<string>;
365
+ }
366
+ ```
367
+
368
+ ### TerminalExecutionResult
369
+
370
+ Result of executing a terminal command.
371
+
372
+ ```typescript
373
+ interface TerminalExecutionResult {
374
+ /** Command that was executed */
375
+ command: string;
376
+ /** Output from the command */
377
+ output: string;
378
+ /** Exit code (0 for success) */
379
+ exitCode: number;
380
+ /** Execution timestamp */
381
+ timestamp: number;
382
+ /** Error message if execution failed */
383
+ error?: string;
384
+ }
385
+ ```
386
+
387
+ ## Schema Validation
388
+
389
+ Terminal nodes are automatically validated when loading schemas:
390
+
391
+ ```typescript
392
+ import { validateSchema, loadSchemaFromFile } from '@plures/praxis';
393
+
394
+ // Validate a schema programmatically
395
+ const result = validateSchema(schema);
396
+ if (!result.valid) {
397
+ console.error('Validation errors:', result.errors);
398
+ }
399
+
400
+ // Load and validate from file
401
+ const fileResult = await loadSchemaFromFile('./schema.yaml');
402
+ if (fileResult.errors.length > 0) {
403
+ console.error('Load errors:', fileResult.errors);
404
+ }
405
+ ```
406
+
407
+ ### Validation Rules
408
+
409
+ - `inputMode` must be either `'text'` or `'widget'`
410
+ - `history` must be an array (if provided)
411
+ - Node `id` is required
412
+ - Node `type` is required
413
+
414
+ ## Examples
415
+
416
+ ### Basic Terminal
417
+
418
+ ```typescript
419
+ import { createTerminalAdapter } from '@plures/praxis';
420
+
421
+ const terminal = createTerminalAdapter({
422
+ nodeId: 'basic-terminal',
423
+ });
424
+
425
+ await terminal.executeCommand('pwd');
426
+ await terminal.executeCommand('ls');
427
+
428
+ console.log(terminal.getHistory()); // ['pwd', 'ls']
429
+ ```
430
+
431
+ ### Terminal with History
432
+
433
+ ```typescript
434
+ const terminal = createTerminalAdapter({
435
+ nodeId: 'history-terminal',
436
+ props: {
437
+ inputMode: 'text',
438
+ history: ['echo "Previous session"'],
439
+ lastOutput: null,
440
+ },
441
+ });
442
+
443
+ await terminal.executeCommand('echo "New session"');
444
+ console.log(terminal.getHistory());
445
+ // ['echo "Previous session"', 'echo "New session"']
446
+ ```
447
+
448
+ ### Loading from YAML
449
+
450
+ ```typescript
451
+ import { loadSchemaFromFile } from '@plures/praxis';
452
+
453
+ const result = await loadSchemaFromFile('./terminal-schema.yaml');
454
+ if (result.schema?.orchestration?.nodes) {
455
+ for (const node of result.schema.orchestration.nodes) {
456
+ if (node.type === 'terminal') {
457
+ console.log(`Found terminal node: ${node.id}`);
458
+ }
459
+ }
460
+ }
461
+ ```
462
+
463
+ ## Integration Points
464
+
465
+ ### PluresDB (Future)
466
+
467
+ Terminal nodes support PluresDB bindings for reactive state management:
468
+
469
+ ```typescript
470
+ const terminal = createTerminalAdapter({
471
+ nodeId: 'reactive-terminal',
472
+ inputPath: '/app/terminal/input', // Listen for commands
473
+ outputPath: '/app/terminal/output', // Publish results
474
+ });
475
+
476
+ // When implemented, commands from inputPath will be auto-executed
477
+ // Results will be auto-synced to outputPath
478
+ ```
479
+
480
+ ### RuneBook (Future)
481
+
482
+ Integration with RuneBook execution model for actual command execution:
483
+
484
+ ```typescript
485
+ // Current: Stubbed execution
486
+ const result = await terminal.executeCommand('npm test');
487
+ // result.output: "[Stub] Command received: npm test..."
488
+
489
+ // Future: Real execution via RuneBook
490
+ // result.output: actual test output
491
+ ```
492
+
493
+ ### Canvas Integration with Svelte Component
494
+
495
+ Visual terminal component for Praxis Canvas is now available! Use the `TerminalNode.svelte` component:
496
+
497
+ ```svelte
498
+ <script>
499
+ import TerminalNode from '@plures/praxis/components/TerminalNode.svelte';
500
+ import { createTerminalAdapter } from '@plures/praxis';
501
+
502
+ const terminal = createTerminalAdapter({
503
+ nodeId: 'visual-terminal',
504
+ props: {
505
+ inputMode: 'widget',
506
+ history: [],
507
+ lastOutput: null,
508
+ },
509
+ });
510
+ </script>
511
+
512
+ <TerminalNode
513
+ adapter={terminal}
514
+ x={100}
515
+ y={100}
516
+ width={600}
517
+ height={400}
518
+ draggable={true}
519
+ resizable={true}
520
+ />
521
+ ```
522
+
523
+ **Component Features:**
524
+ - Drag and drop positioning
525
+ - Resizable dimensions
526
+ - Context menu operations
527
+ - Dark VS Code-inspired theme
528
+ - Both text and widget input modes
529
+ - Command history display
530
+ - Real-time output rendering
531
+
532
+ See [examples/terminal-canvas/](../examples/terminal-canvas/) for a complete working example.
533
+
534
+ ## Testing
535
+
536
+ The terminal node implementation includes comprehensive tests:
537
+
538
+ ```bash
539
+ npm test
540
+ ```
541
+
542
+ Tests cover:
543
+ - Schema validation with various configurations
544
+ - YAML and JSON loading
545
+ - Terminal adapter creation and configuration
546
+ - Command execution and history management
547
+ - Property updates and state management
548
+ - PluresDB binding configuration
549
+
550
+ ## Future Enhancements
551
+
552
+ 1. **RuneBook Integration**: Full command execution via RuneBook
553
+ 2. **PluresDB Sync**: Real-time reactive state synchronization
554
+ 3. **Security**: Command sandboxing and permission system
555
+ 4. **Streaming**: Real-time command output streaming
556
+ 5. **Environment**: Custom environment variables per terminal
557
+ 6. **Multiplexing**: Multiple terminal sessions in one node
558
+ 7. **Persistence**: Save/restore terminal sessions
559
+ 8. **Node Wiring**: Connect terminals to InputNode, DisplayNode, and AgentNode
560
+
561
+ ## Migration Guide
562
+
563
+ No migration needed - this is a new feature. Existing Praxis applications continue to work without changes.
564
+
565
+ To adopt terminal nodes:
566
+
567
+ 1. Update to latest Praxis version
568
+ 2. Add terminal nodes to your schema
569
+ 3. Create terminal adapters in your runtime code
570
+ 4. Start executing commands!
571
+
572
+ ## Best Practices
573
+
574
+ 1. **Use Bindings**: Define input/output bindings for reactive integration
575
+ 2. **Track History**: Monitor command history for debugging
576
+ 3. **Error Handling**: Check `exitCode` and `error` in execution results
577
+ 4. **State Management**: Use `getState()` to inspect terminal state
578
+ 5. **Clean Up**: Call `clearHistory()` when needed to manage memory
579
+
580
+ ## Support
581
+
582
+ For questions, issues, or feature requests:
583
+ - GitHub Issues: https://github.com/plures/praxis/issues
584
+ - Documentation: https://github.com/plures/praxis/tree/main/docs
585
+
586
+ ## License
587
+
588
+ Terminal Node is part of Praxis and follows the same MIT license.