@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.
- package/FRAMEWORK.md +420 -0
- package/LICENSE +21 -0
- package/README.md +1310 -0
- package/dist/adapters/cli.d.ts +43 -0
- package/dist/adapters/cli.d.ts.map +1 -0
- package/dist/adapters/cli.js +126 -0
- package/dist/adapters/cli.js.map +1 -0
- package/dist/cli/commands/auth.d.ts +26 -0
- package/dist/cli/commands/auth.d.ts.map +1 -0
- package/dist/cli/commands/auth.js +233 -0
- package/dist/cli/commands/auth.js.map +1 -0
- package/dist/cli/commands/cloud.d.ts +27 -0
- package/dist/cli/commands/cloud.d.ts.map +1 -0
- package/dist/cli/commands/cloud.js +232 -0
- package/dist/cli/commands/cloud.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +25 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +168 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +179 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cloud/auth.d.ts +51 -0
- package/dist/cloud/auth.d.ts.map +1 -0
- package/dist/cloud/auth.js +194 -0
- package/dist/cloud/auth.js.map +1 -0
- package/dist/cloud/billing.d.ts +184 -0
- package/dist/cloud/billing.d.ts.map +1 -0
- package/dist/cloud/billing.js +179 -0
- package/dist/cloud/billing.js.map +1 -0
- package/dist/cloud/client.d.ts +39 -0
- package/dist/cloud/client.d.ts.map +1 -0
- package/dist/cloud/client.js +176 -0
- package/dist/cloud/client.js.map +1 -0
- package/dist/cloud/index.d.ts +44 -0
- package/dist/cloud/index.d.ts.map +1 -0
- package/dist/cloud/index.js +44 -0
- package/dist/cloud/index.js.map +1 -0
- package/dist/cloud/marketplace.d.ts +166 -0
- package/dist/cloud/marketplace.d.ts.map +1 -0
- package/dist/cloud/marketplace.js +159 -0
- package/dist/cloud/marketplace.js.map +1 -0
- package/dist/cloud/provisioning.d.ts +110 -0
- package/dist/cloud/provisioning.d.ts.map +1 -0
- package/dist/cloud/provisioning.js +148 -0
- package/dist/cloud/provisioning.js.map +1 -0
- package/dist/cloud/relay/endpoints.d.ts +62 -0
- package/dist/cloud/relay/endpoints.d.ts.map +1 -0
- package/dist/cloud/relay/endpoints.js +217 -0
- package/dist/cloud/relay/endpoints.js.map +1 -0
- package/dist/cloud/relay/health/index.d.ts +5 -0
- package/dist/cloud/relay/health/index.d.ts.map +1 -0
- package/dist/cloud/relay/health/index.js +9 -0
- package/dist/cloud/relay/health/index.js.map +1 -0
- package/dist/cloud/relay/stats/index.d.ts +5 -0
- package/dist/cloud/relay/stats/index.d.ts.map +1 -0
- package/dist/cloud/relay/stats/index.js +9 -0
- package/dist/cloud/relay/stats/index.js.map +1 -0
- package/dist/cloud/relay/sync/index.d.ts +5 -0
- package/dist/cloud/relay/sync/index.d.ts.map +1 -0
- package/dist/cloud/relay/sync/index.js +9 -0
- package/dist/cloud/relay/sync/index.js.map +1 -0
- package/dist/cloud/relay/usage/index.d.ts +5 -0
- package/dist/cloud/relay/usage/index.d.ts.map +1 -0
- package/dist/cloud/relay/usage/index.js +9 -0
- package/dist/cloud/relay/usage/index.js.map +1 -0
- package/dist/cloud/sponsors.d.ts +81 -0
- package/dist/cloud/sponsors.d.ts.map +1 -0
- package/dist/cloud/sponsors.js +130 -0
- package/dist/cloud/sponsors.js.map +1 -0
- package/dist/cloud/types.d.ts +169 -0
- package/dist/cloud/types.d.ts.map +1 -0
- package/dist/cloud/types.js +7 -0
- package/dist/cloud/types.js.map +1 -0
- package/dist/components/index.d.ts +43 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +17 -0
- package/dist/components/index.js.map +1 -0
- package/dist/core/actors.d.ts +95 -0
- package/dist/core/actors.d.ts.map +1 -0
- package/dist/core/actors.js +158 -0
- package/dist/core/actors.js.map +1 -0
- package/dist/core/component/generator.d.ts +122 -0
- package/dist/core/component/generator.d.ts.map +1 -0
- package/dist/core/component/generator.js +307 -0
- package/dist/core/component/generator.js.map +1 -0
- package/dist/core/engine.d.ts +92 -0
- package/dist/core/engine.d.ts.map +1 -0
- package/dist/core/engine.js +199 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/introspection.d.ts +141 -0
- package/dist/core/introspection.d.ts.map +1 -0
- package/dist/core/introspection.js +208 -0
- package/dist/core/introspection.js.map +1 -0
- package/dist/core/logic/generator.d.ts +76 -0
- package/dist/core/logic/generator.d.ts.map +1 -0
- package/dist/core/logic/generator.js +339 -0
- package/dist/core/logic/generator.js.map +1 -0
- package/dist/core/pluresdb/generator.d.ts +58 -0
- package/dist/core/pluresdb/generator.d.ts.map +1 -0
- package/dist/core/pluresdb/generator.js +162 -0
- package/dist/core/pluresdb/generator.js.map +1 -0
- package/dist/core/protocol.d.ts +121 -0
- package/dist/core/protocol.d.ts.map +1 -0
- package/dist/core/protocol.js +46 -0
- package/dist/core/protocol.js.map +1 -0
- package/dist/core/rules.d.ts +120 -0
- package/dist/core/rules.d.ts.map +1 -0
- package/dist/core/rules.js +81 -0
- package/dist/core/rules.js.map +1 -0
- package/dist/core/schema/loader.d.ts +47 -0
- package/dist/core/schema/loader.d.ts.map +1 -0
- package/dist/core/schema/loader.js +189 -0
- package/dist/core/schema/loader.js.map +1 -0
- package/dist/core/schema/normalize.d.ts +72 -0
- package/dist/core/schema/normalize.d.ts.map +1 -0
- package/dist/core/schema/normalize.js +190 -0
- package/dist/core/schema/normalize.js.map +1 -0
- package/dist/core/schema/types.d.ts +370 -0
- package/dist/core/schema/types.d.ts.map +1 -0
- package/dist/core/schema/types.js +161 -0
- package/dist/core/schema/types.js.map +1 -0
- package/dist/dsl/index.d.ts +152 -0
- package/dist/dsl/index.d.ts.map +1 -0
- package/dist/dsl/index.js +132 -0
- package/dist/dsl/index.js.map +1 -0
- package/dist/dsl.d.ts +124 -0
- package/dist/dsl.d.ts.map +1 -0
- package/dist/dsl.js +130 -0
- package/dist/dsl.js.map +1 -0
- package/dist/examples/advanced-todo/index.d.ts +55 -0
- package/dist/examples/advanced-todo/index.d.ts.map +1 -0
- package/dist/examples/advanced-todo/index.js +222 -0
- package/dist/examples/advanced-todo/index.js.map +1 -0
- package/dist/examples/auth-basic/index.d.ts +17 -0
- package/dist/examples/auth-basic/index.d.ts.map +1 -0
- package/dist/examples/auth-basic/index.js +122 -0
- package/dist/examples/auth-basic/index.js.map +1 -0
- package/dist/examples/cart/index.d.ts +19 -0
- package/dist/examples/cart/index.d.ts.map +1 -0
- package/dist/examples/cart/index.js +202 -0
- package/dist/examples/cart/index.js.map +1 -0
- package/dist/examples/hero-ecommerce/index.d.ts +39 -0
- package/dist/examples/hero-ecommerce/index.d.ts.map +1 -0
- package/dist/examples/hero-ecommerce/index.js +506 -0
- package/dist/examples/hero-ecommerce/index.js.map +1 -0
- package/dist/examples/svelte-counter/index.d.ts +31 -0
- package/dist/examples/svelte-counter/index.d.ts.map +1 -0
- package/dist/examples/svelte-counter/index.js +123 -0
- package/dist/examples/svelte-counter/index.js.map +1 -0
- package/dist/flows.d.ts +125 -0
- package/dist/flows.d.ts.map +1 -0
- package/dist/flows.js +160 -0
- package/dist/flows.js.map +1 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/pluresdb.d.ts +56 -0
- package/dist/integrations/pluresdb.d.ts.map +1 -0
- package/dist/integrations/pluresdb.js +46 -0
- package/dist/integrations/pluresdb.js.map +1 -0
- package/dist/integrations/svelte.d.ts +306 -0
- package/dist/integrations/svelte.d.ts.map +1 -0
- package/dist/integrations/svelte.js +447 -0
- package/dist/integrations/svelte.js.map +1 -0
- package/dist/registry.d.ts +94 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +181 -0
- package/dist/registry.js.map +1 -0
- package/dist/runtime/terminal-adapter.d.ts +105 -0
- package/dist/runtime/terminal-adapter.d.ts.map +1 -0
- package/dist/runtime/terminal-adapter.js +113 -0
- package/dist/runtime/terminal-adapter.js.map +1 -0
- package/dist/step.d.ts +34 -0
- package/dist/step.d.ts.map +1 -0
- package/dist/step.js +111 -0
- package/dist/step.js.map +1 -0
- package/dist/types.d.ts +63 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/docs/MONETIZATION.md +394 -0
- package/docs/TERMINAL_NODE.md +588 -0
- package/docs/guides/canvas.md +389 -0
- package/docs/guides/getting-started.md +347 -0
- package/docs/guides/history-state-pattern.md +618 -0
- package/docs/guides/orchestration.md +617 -0
- package/docs/guides/parallel-state-pattern.md +767 -0
- package/docs/guides/svelte-integration.md +691 -0
- package/package.json +96 -0
- package/src/__tests__/actors.test.ts +270 -0
- package/src/__tests__/billing.test.ts +175 -0
- package/src/__tests__/cloud.test.ts +247 -0
- package/src/__tests__/dsl.test.ts +154 -0
- package/src/__tests__/edge-cases.test.ts +475 -0
- package/src/__tests__/engine.test.ts +137 -0
- package/src/__tests__/generators.test.ts +270 -0
- package/src/__tests__/introspection.test.ts +321 -0
- package/src/__tests__/protocol.test.ts +40 -0
- package/src/__tests__/provisioning.test.ts +162 -0
- package/src/__tests__/schema.test.ts +241 -0
- package/src/__tests__/svelte-integration.test.ts +431 -0
- package/src/__tests__/terminal-node.test.ts +352 -0
- package/src/adapters/cli.ts +175 -0
- package/src/cli/commands/auth.ts +271 -0
- package/src/cli/commands/cloud.ts +281 -0
- package/src/cli/commands/generate.ts +225 -0
- package/src/cli/index.ts +190 -0
- package/src/cloud/README.md +383 -0
- package/src/cloud/auth.ts +245 -0
- package/src/cloud/billing.ts +336 -0
- package/src/cloud/client.ts +221 -0
- package/src/cloud/index.ts +121 -0
- package/src/cloud/marketplace.ts +303 -0
- package/src/cloud/provisioning.ts +254 -0
- package/src/cloud/relay/endpoints.ts +307 -0
- package/src/cloud/relay/health/function.json +17 -0
- package/src/cloud/relay/health/index.ts +10 -0
- package/src/cloud/relay/host.json +15 -0
- package/src/cloud/relay/local.settings.json +8 -0
- package/src/cloud/relay/stats/function.json +17 -0
- package/src/cloud/relay/stats/index.ts +10 -0
- package/src/cloud/relay/sync/function.json +17 -0
- package/src/cloud/relay/sync/index.ts +10 -0
- package/src/cloud/relay/usage/function.json +17 -0
- package/src/cloud/relay/usage/index.ts +10 -0
- package/src/cloud/sponsors.ts +213 -0
- package/src/cloud/types.ts +198 -0
- package/src/components/README.md +125 -0
- package/src/components/TerminalNode.svelte +457 -0
- package/src/components/index.ts +46 -0
- package/src/core/actors.ts +205 -0
- package/src/core/component/generator.ts +432 -0
- package/src/core/engine.ts +243 -0
- package/src/core/introspection.ts +329 -0
- package/src/core/logic/generator.ts +420 -0
- package/src/core/pluresdb/generator.ts +229 -0
- package/src/core/protocol.ts +132 -0
- package/src/core/rules.ts +167 -0
- package/src/core/schema/loader.ts +247 -0
- package/src/core/schema/normalize.ts +322 -0
- package/src/core/schema/types.ts +557 -0
- package/src/dsl/index.ts +218 -0
- package/src/dsl.ts +214 -0
- package/src/examples/advanced-todo/App.svelte +506 -0
- package/src/examples/advanced-todo/README.md +371 -0
- package/src/examples/advanced-todo/index.ts +309 -0
- package/src/examples/auth-basic/index.ts +163 -0
- package/src/examples/cart/index.ts +259 -0
- package/src/examples/hero-ecommerce/index.ts +657 -0
- package/src/examples/svelte-counter/index.ts +168 -0
- package/src/flows.ts +268 -0
- package/src/index.ts +154 -0
- package/src/integrations/pluresdb.ts +93 -0
- package/src/integrations/svelte.ts +617 -0
- package/src/registry.ts +223 -0
- package/src/runtime/terminal-adapter.ts +175 -0
- package/src/step.ts +151 -0
- package/src/types.ts +70 -0
- package/templates/basic-app/README.md +147 -0
- 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.
|