citadel_cli 1.0.0 → 1.1.3
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/README.md +149 -210
- package/dist/App.d.ts +2 -0
- package/dist/__test-utils__/factories.d.ts +40 -0
- package/dist/citadel.css +1 -1
- package/dist/citadel.es.js +1271 -1418
- package/dist/citadel.umd.js +34 -19
- package/dist/components/Citadel/Citadel.d.ts +15 -0
- package/dist/components/Citadel/components/AvailableCommands.d.ts +2 -0
- package/dist/{src/components → components}/Citadel/components/CommandInput.d.ts +0 -2
- package/dist/components/Citadel/config/CitadelConfigContext.d.ts +18 -0
- package/dist/{src/components → components}/Citadel/config/defaults.d.ts +15 -7
- package/dist/components/Citadel/config/hooks.d.ts +4 -0
- package/dist/{src/components → components}/Citadel/config/types.d.ts +32 -20
- package/dist/{src/components → components}/Citadel/hooks/useCitadelState.d.ts +2 -1
- package/dist/components/Citadel/hooks/useCommandHistory.d.ts +27 -0
- package/dist/components/Citadel/hooks/useCommandParser.d.ts +22 -0
- package/dist/components/Citadel/hooks/useSegmentStack.d.ts +14 -0
- package/dist/components/Citadel/hooks/useSegmentStackVersion.d.ts +1 -0
- package/dist/{src/components → components}/Citadel/storage/BaseStorage.d.ts +2 -2
- package/dist/{src/components → components}/Citadel/storage/LocalStorage.d.ts +1 -1
- package/dist/{src/components → components}/Citadel/storage/MemoryStorage.d.ts +2 -2
- package/dist/components/Citadel/types/command-registry.d.ts +88 -0
- package/dist/{src/components → components}/Citadel/types/command-results.d.ts +2 -2
- package/dist/components/Citadel/types/help-command.d.ts +3 -0
- package/dist/components/Citadel/types/segment-stack.d.ts +62 -0
- package/dist/{src/components → components}/Citadel/types/state.d.ts +8 -22
- package/dist/{src/components → components}/Citadel/types/storage.d.ts +4 -3
- package/dist/components/Citadel/utils/logger.d.ts +21 -0
- package/dist/index.d.ts +4 -2
- package/package.json +12 -5
- package/dist/command_examples/basic-commands.d.ts +0 -83
- package/dist/dist/styles.css +0 -789
- package/dist/src/App.d.ts +0 -4
- package/dist/src/__test-utils__/factories.d.ts +0 -21
- package/dist/src/components/Citadel/Citadel.d.ts +0 -11
- package/dist/src/components/Citadel/commands/history-commands.d.ts +0 -2
- package/dist/src/components/Citadel/components/AvailableCommands.d.ts +0 -9
- package/dist/src/components/Citadel/config/CitadelConfigContext.d.ts +0 -11
- package/dist/src/components/Citadel/hooks/useCommandHistory.d.ts +0 -17
- package/dist/src/components/Citadel/hooks/useCommandParser.d.ts +0 -19
- package/dist/src/components/Citadel/hooks/useCommandTrie.d.ts +0 -2
- package/dist/src/components/Citadel/types/command-context.d.ts +0 -4
- package/dist/src/components/Citadel/types/command-trie.d.ts +0 -238
- package/dist/src/components/Citadel/types/help-command.d.ts +0 -3
- package/dist/src/components/Citadel/utils/keySimulation.d.ts +0 -2
- package/dist/src/index.d.ts +0 -4
- /package/dist/{src/components → components}/Citadel/Cursor.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/__tests__/Citadel.test.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/components/CommandOutput.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/components/CommandOutputLine.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/components/Spinner.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/components/__tests__/AvailableCommands.test.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/components/__tests__/CommandInput.test.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/components/__tests__/CommandOutput.test.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/components/__tests__/CommandOutputLine.test.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/components/__tests__/Spinner.test.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/config/__tests__/CitadelConfigContext.test.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/hooks/__tests__/useCitadelState.test.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/hooks/__tests__/useCommandHistory.test.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/hooks/__tests__/useCommandParser.test.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/hooks/useGlobalShortcut.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/hooks/useSlideAnimation.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/index.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/services/HistoryService.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/storage/StorageFactory.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/storage/__tests__/LocalStorage.test.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/storage/__tests__/MemoryStorage.test.d.ts +0 -0
- /package/dist/{src/components/Citadel/hooks/__tests__/useCommandTrie.test.d.ts → components/Citadel/types/__tests__/command-registry.test.d.ts} +0 -0
- /package/dist/{src/components/Citadel/types/__tests__/command-trie.test.d.ts → components/Citadel/types/__tests__/segment-stack.test.d.ts} +0 -0
- /package/dist/{src/components → components}/Citadel/types/cursor.d.ts +0 -0
- /package/dist/{src/components → components}/Citadel/types/index.d.ts +0 -0
- /package/dist/{src/main.d.ts → main.d.ts} +0 -0
- /package/dist/{src/test → test}/setup.d.ts +0 -0
package/README.md
CHANGED
|
@@ -1,257 +1,208 @@
|
|
|
1
|
-
# Citadel
|
|
1
|
+
# Citadel CLI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Citadel CLI enhances React applications by adding a keyboard-driven command line component to your application, allowing rapid task execution for power users and developers.
|
|
4
|
+
|
|
5
|
+
## Use Cases
|
|
6
|
+
|
|
7
|
+
- **API Testing & Debugging**: Execute REST calls, inspect responses, and manipulate cookies/localStorage without leaving your
|
|
8
|
+
application context
|
|
9
|
+
- **Power User Workflows**: Transform repetitive click-through sequences into fast keyboard commands for advanced users
|
|
10
|
+
- **DevOps Integration**: Add command-line control to CI/CD dashboards and deployment tools for rapid operations
|
|
11
|
+
- **Internal Tool Enhancement**: Give your team's web applications the speed and efficiency of terminal interfaces
|
|
12
|
+
- Perform (multiple) REST API calls & view results, view/modify cookies/localstorage. Do JavaScript things without affecting the application.
|
|
13
|
+
|
|
14
|
+

|
|
15
|
+
|
|
16
|
+
# Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install citadel_cli
|
|
20
|
+
```
|
|
4
21
|
|
|
5
22
|
## Quick Start
|
|
6
23
|
|
|
24
|
+
In your application:
|
|
25
|
+
|
|
7
26
|
```typescript
|
|
8
|
-
import { Citadel, CommandTrie } from 'citadel';
|
|
9
|
-
|
|
10
|
-
// Initialize command system
|
|
11
|
-
const commands = new CommandTrie();
|
|
12
|
-
|
|
13
|
-
// Register commands
|
|
14
|
-
commands.addCommand(
|
|
15
|
-
['customer', 'search'],
|
|
16
|
-
'Search for customer records',
|
|
17
|
-
async (args) => ({
|
|
18
|
-
json: await customerService.search(args.query)
|
|
19
|
-
}),
|
|
20
|
-
{ name: 'query', description: 'Customer name or ID' }
|
|
21
|
-
);
|
|
22
27
|
|
|
23
|
-
|
|
28
|
+
import { Citadel } from "citadel_cli";
|
|
29
|
+
|
|
24
30
|
function App() {
|
|
25
31
|
return (
|
|
26
|
-
|
|
27
|
-
<Citadel
|
|
28
|
-
|
|
29
|
-
</div>
|
|
32
|
+
<>
|
|
33
|
+
<Citadel />
|
|
34
|
+
</>
|
|
30
35
|
);
|
|
31
36
|
}
|
|
32
37
|
```
|
|
33
38
|
|
|
34
|
-
|
|
39
|
+
Press <kbd>.</kbd> (period) to activate Citadel.
|
|
35
40
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
Now this doesn't do much, yet: it just shows the "help" command. You can
|
|
42
|
+
execute it by pressing <kbd>h[Enter]</kbd>. If you do then you should see the
|
|
43
|
+
following:
|
|
44
|
+
|
|
45
|
+

|
|
46
|
+
|
|
47
|
+
## Adding Commands
|
|
48
|
+
|
|
49
|
+
To add your own commands:
|
|
41
50
|
|
|
51
|
+
1. Create a `CommandRegistry` object
|
|
52
|
+
2. Add commands to the registry object via the `addCommand` function
|
|
53
|
+
3. Pass the registry to the `Citadel` component
|
|
42
54
|
|
|
43
|
-
|
|
55
|
+
For example, let's add a simple `greet` command.
|
|
44
56
|
|
|
45
|
-
Commands can be typed using abbreviated forms. For example:
|
|
46
57
|
```
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
58
|
+
import { Citadel, CommandRegistry, TextCommandResult } from "citadel_cli";
|
|
59
|
+
|
|
60
|
+
// 1. Create the registry where your commands will be stored
|
|
61
|
+
const cmdRegistry = new CommandRegistry();
|
|
62
|
+
|
|
63
|
+
// 2. Add a command to the registry. This can be called as many times as you like.
|
|
64
|
+
cmdRegistry.addCommand(
|
|
65
|
+
[
|
|
66
|
+
{ type: 'word', name: 'greet' },
|
|
67
|
+
{ type: 'argument', name: 'name', description: 'Enter your name' }
|
|
68
|
+
],
|
|
69
|
+
'Say hello to the world', // The description of this command. Used by "help".
|
|
70
|
+
|
|
71
|
+
// Next comes the "handler", which is what will get called when the user hits enter.
|
|
72
|
+
// The return type for this handler is `TextCommandResult`. There are other
|
|
73
|
+
// types of command result that we'll cover later.
|
|
74
|
+
async (args: string[]) => new TextCommandResult(`Hello, ${args[0]}!`)
|
|
75
|
+
);
|
|
50
76
|
```
|
|
77
|
+
The first argument to the `addCommand` function is an array of "command
|
|
78
|
+
segments". There are two types of command segments: `word`s and `argument`s.
|
|
79
|
+
Here we are defining a command with two segments named `greet` and `name`.
|
|
80
|
+
`greet` being a `word` segment and `name` being an `argument`.
|
|
51
81
|
|
|
52
|
-
|
|
82
|
+
Word segments are autocompleted, whereas argument segments are used to store
|
|
83
|
+
user-entered values.
|
|
53
84
|
|
|
54
|
-
|
|
85
|
+
A few notes on arguments:
|
|
55
86
|
|
|
56
|
-
|
|
87
|
+
1. You can have zero or more arguments in a command, and they can appear in any
|
|
88
|
+
order.
|
|
89
|
+
2. The arguments the user enters will be passed to the handler as an array of
|
|
90
|
+
strings.
|
|
91
|
+
3. Arguments can be single- or double-quoted. This allows users to enter in
|
|
92
|
+
values that have spaces or other special characters.
|
|
57
93
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
94
|
+
Continuing on with our `greet` example, after the segments are defined is a
|
|
95
|
+
description ("Say hello..."). This is the text that will be shown by the help
|
|
96
|
+
command.
|
|
97
|
+
|
|
98
|
+
The final argument to `addCommand` is the *handler*. Let's go over that:
|
|
61
99
|
|
|
62
|
-
|
|
100
|
+
```
|
|
101
|
+
async (args: string[]) => new TextCommandResult(`Hello, ${args[0]}!`)
|
|
102
|
+
```
|
|
63
103
|
|
|
64
|
-
|
|
104
|
+
As mentioned before this is what will be called after the user hits Enter. The
|
|
105
|
+
values for the arguments entered by the user (if any) are passed in to the
|
|
106
|
+
handler as `args: string[]`. What you do inside the handler is completely up to
|
|
107
|
+
your imagination. For example, say you wanted to clear the localstorage:
|
|
65
108
|
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
['refresh', 'cache'],
|
|
69
|
-
'Refresh application cache',
|
|
70
|
-
async () => {
|
|
71
|
-
// Clear local storage
|
|
109
|
+
```
|
|
110
|
+
async (_args: string[]) => {
|
|
72
111
|
localStorage.clear();
|
|
73
|
-
|
|
74
|
-
store.dispatch(resetState());
|
|
75
|
-
// Reload application
|
|
76
|
-
window.location.reload();
|
|
77
|
-
return { json: { status: 'Cache cleared' } };
|
|
112
|
+
return new TextCommandResult('localStorage cleared!');
|
|
78
113
|
}
|
|
79
|
-
);
|
|
80
114
|
```
|
|
81
115
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
Commands can return different types of results:
|
|
85
|
-
- JSON data for structured information
|
|
86
|
-
- React components for rich visualizations
|
|
87
|
-
- Plain text for simple outputs
|
|
88
|
-
- Promises for async operations
|
|
116
|
+
Or perhaps make an HTTP POST and return the result as JSON:
|
|
89
117
|
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
})
|
|
99
|
-
);
|
|
118
|
+
```
|
|
119
|
+
async (args: string[]) => {
|
|
120
|
+
const response = await fetch('https://api.example.com/endpoint', {
|
|
121
|
+
method: 'POST',
|
|
122
|
+
headers: {
|
|
123
|
+
'Content-Type': 'application/json',
|
|
124
|
+
},
|
|
125
|
+
body: JSON.stringify({ name: args[0] }),
|
|
126
|
+
});
|
|
127
|
+
return new JsonCommandResult(await response.json());
|
|
128
|
+
}
|
|
100
129
|
```
|
|
101
130
|
|
|
102
|
-
|
|
131
|
+
At the time of this writing the following command result types are available:
|
|
103
132
|
|
|
104
|
-
|
|
133
|
+
- `ErrorCommandResult`
|
|
134
|
+
- `ImageCommandResult`
|
|
135
|
+
- `JsonCommandResult`
|
|
136
|
+
- `TextCommandResult`
|
|
105
137
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
commands.addCommand(
|
|
109
|
-
['ticket', 'new'],
|
|
110
|
-
'Create support ticket',
|
|
111
|
-
async (args) => {
|
|
112
|
-
const ticket = await ticketService.create({
|
|
113
|
-
customerId: args.customer,
|
|
114
|
-
priority: args.priority,
|
|
115
|
-
description: args.description
|
|
116
|
-
});
|
|
117
|
-
return { json: { ticketId: ticket.id, status: 'created' } };
|
|
118
|
-
},
|
|
119
|
-
[
|
|
120
|
-
{ name: 'customer', description: 'Customer ID' },
|
|
121
|
-
{ name: 'priority', description: 'Ticket priority (high|medium|low)' },
|
|
122
|
-
{ name: 'description', description: 'Issue description' }
|
|
123
|
-
]
|
|
124
|
-
);
|
|
138
|
+
Back to our `greeting` command. The final code for it (without comments) should
|
|
139
|
+
now look like this:
|
|
125
140
|
|
|
126
|
-
commands.addCommand(
|
|
127
|
-
['customer', 'history'],
|
|
128
|
-
'View customer interaction history',
|
|
129
|
-
async (args) => ({
|
|
130
|
-
json: await customerService.getHistory(args.id, {
|
|
131
|
-
last: args.days || 30
|
|
132
|
-
})
|
|
133
|
-
}),
|
|
134
|
-
[
|
|
135
|
-
{ name: 'id', description: 'Customer ID' },
|
|
136
|
-
{ name: 'days', description: 'Number of days (default: 30)' }
|
|
137
|
-
]
|
|
138
|
-
);
|
|
139
141
|
```
|
|
142
|
+
import { CommandRegistry, TextCommandResult } from "citadel_cli";
|
|
140
143
|
|
|
141
|
-
|
|
144
|
+
const cmdRegistry = new CommandRegistry();
|
|
142
145
|
|
|
143
|
-
|
|
144
|
-
// Trading command configuration
|
|
145
|
-
commands.addCommand(
|
|
146
|
-
['trade', 'limit'],
|
|
147
|
-
'Place limit order',
|
|
148
|
-
async (args) => {
|
|
149
|
-
const order = await tradingService.placeLimitOrder({
|
|
150
|
-
pair: args.pair,
|
|
151
|
-
price: args.price,
|
|
152
|
-
quantity: args.quantity,
|
|
153
|
-
side: args.side || 'buy'
|
|
154
|
-
});
|
|
155
|
-
return { json: { orderId: order.id, status: order.status } };
|
|
156
|
-
},
|
|
146
|
+
cmdRegistry.addCommand(
|
|
157
147
|
[
|
|
158
|
-
{
|
|
159
|
-
{ name: '
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
]
|
|
148
|
+
{ type: 'word', name: 'greet' },
|
|
149
|
+
{ type: 'argument', name: 'name', description: 'Enter your name' }
|
|
150
|
+
],
|
|
151
|
+
'Say hello to the world',
|
|
152
|
+
async (args: string[]) => new TextCommandResult(`Hello, ${args[0]}!`)
|
|
163
153
|
);
|
|
164
154
|
```
|
|
155
|
+
Now that the command has been added all that is left is to pass the registry to
|
|
156
|
+
the `Citadel` component:
|
|
165
157
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
```typescript
|
|
169
|
-
// Deployment command configuration
|
|
170
|
-
commands.addCommand(
|
|
171
|
-
['deploy', 'status'],
|
|
172
|
-
'Check deployment status',
|
|
173
|
-
async (args) => ({
|
|
174
|
-
json: await deploymentService.getStatus(args.service, args.environment)
|
|
175
|
-
}),
|
|
176
|
-
[
|
|
177
|
-
{ name: 'service', description: 'Service name' },
|
|
178
|
-
{ name: 'environment', description: 'Environment (dev|staging|prod)' }
|
|
179
|
-
]
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
commands.addCommand(
|
|
183
|
-
['metrics', 'alert'],
|
|
184
|
-
'Configure service alerts',
|
|
185
|
-
async (args) => ({
|
|
186
|
-
json: await metricsService.setAlert(args.service, {
|
|
187
|
-
metric: args.metric,
|
|
188
|
-
threshold: args.threshold,
|
|
189
|
-
duration: args.duration
|
|
190
|
-
})
|
|
191
|
-
}),
|
|
192
|
-
[
|
|
193
|
-
{ name: 'service', description: 'Service name' },
|
|
194
|
-
{ name: 'metric', description: 'Metric name (cpu|memory|latency)' },
|
|
195
|
-
{ name: 'threshold', description: 'Alert threshold' },
|
|
196
|
-
{ name: 'duration', description: 'Duration in minutes' }
|
|
197
|
-
]
|
|
198
|
-
);
|
|
158
|
+
```
|
|
159
|
+
<Citadel commandRegistry={cmdRegistry} />
|
|
199
160
|
```
|
|
200
161
|
|
|
201
|
-
|
|
162
|
+
The result of this should look like this:
|
|
202
163
|
|
|
203
|
-
|
|
164
|
+

|
|
204
165
|
|
|
205
|
-
|
|
166
|
+
Go forth and make your application experience better!
|
|
206
167
|
|
|
207
|
-
|
|
208
|
-
commands.addCommand(
|
|
209
|
-
['dashboard', 'metrics'],
|
|
210
|
-
'Show service metrics',
|
|
211
|
-
async (args) => ({
|
|
212
|
-
component: <MetricsVisualization serviceId={args.service} />,
|
|
213
|
-
json: await metricsService.get(args.service)
|
|
214
|
-
}),
|
|
215
|
-
{ name: 'service', description: 'Service ID' }
|
|
216
|
-
);
|
|
217
|
-
```
|
|
168
|
+
## Configuration
|
|
218
169
|
|
|
219
|
-
|
|
170
|
+
Certain configuration options can be passed to the Citadel component. These are
|
|
171
|
+
given below, along with their default values.
|
|
220
172
|
|
|
221
|
-
```
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
173
|
+
```
|
|
174
|
+
const config = {
|
|
175
|
+
commandTimeoutMs: 10000,
|
|
176
|
+
includeHelpCommand: true,
|
|
177
|
+
maxHeight: '80vh',
|
|
178
|
+
initialHeight: '40vh',
|
|
179
|
+
minHeight: '200',
|
|
180
|
+
outputFontSize: '0.875rem',
|
|
181
|
+
resetStateOnHide: false,
|
|
182
|
+
showCitadelKey: '.',
|
|
183
|
+
cursorType: 'bbs', // 'blink', 'spin', 'solid', or 'bbs'
|
|
184
|
+
cursorSpeed: 530,
|
|
185
|
+
storage: {
|
|
186
|
+
type: 'localStorage',
|
|
187
|
+
maxCommands: 100
|
|
188
|
+
}
|
|
230
189
|
};
|
|
231
190
|
```
|
|
232
191
|
|
|
233
|
-
|
|
192
|
+
Then to make the component aware of them:
|
|
234
193
|
|
|
235
|
-
### Project Structure
|
|
236
194
|
```
|
|
237
|
-
|
|
238
|
-
├── src/
|
|
239
|
-
│ ├── components/ # React components
|
|
240
|
-
│ ├── styles/ # CSS and theme files
|
|
241
|
-
│ ├── types/ # TypeScript definitions
|
|
242
|
-
│ └── utils/ # Utility functions
|
|
243
|
-
├── public/ # Static assets
|
|
244
|
-
└── vite.config.ts # Vite configuration
|
|
195
|
+
<Citadel commandRegistry={cmdRegistry} config={config} />
|
|
245
196
|
```
|
|
246
197
|
|
|
247
|
-
|
|
198
|
+
## Contributing
|
|
248
199
|
|
|
249
200
|
Contributions are welcome.
|
|
250
201
|
|
|
251
202
|
1. Clone the repository:
|
|
252
203
|
```bash
|
|
253
|
-
git clone https://github.com/jchilders/
|
|
254
|
-
cd
|
|
204
|
+
git clone https://github.com/jchilders/citadel_cli.git
|
|
205
|
+
cd citadel_cli
|
|
255
206
|
```
|
|
256
207
|
|
|
257
208
|
2. Install dependencies:
|
|
@@ -271,10 +222,12 @@ npm link
|
|
|
271
222
|
|
|
272
223
|
5. (Optional) From the directory of the project you want to import Citadel into:
|
|
273
224
|
```bash
|
|
274
|
-
npm link
|
|
275
|
-
# ... your normal
|
|
225
|
+
npm unlink citadel_cli && npm link citadel_cli
|
|
226
|
+
# ... your normal dev process ...
|
|
276
227
|
```
|
|
277
228
|
|
|
229
|
+
Load your appliation and press <kbd>.</kbd>
|
|
230
|
+
|
|
278
231
|
### Bug Reports and Feature Requests
|
|
279
232
|
|
|
280
233
|
- Use the GitHub Issues section to report bugs or suggest features
|
|
@@ -299,7 +252,7 @@ npm link @jchilders/citadel
|
|
|
299
252
|
4. Write or update tests as needed
|
|
300
253
|
5. Run the test suite to ensure everything passes:
|
|
301
254
|
```bash
|
|
302
|
-
npm test
|
|
255
|
+
npm run test
|
|
303
256
|
```
|
|
304
257
|
6. Commit your changes with a clear and descriptive commit message
|
|
305
258
|
7. Push to your fork and submit a pull request
|
|
@@ -321,17 +274,3 @@ npm link @jchilders/citadel
|
|
|
321
274
|
- Keep functions focused and modular
|
|
322
275
|
- Use consistent formatting (the project uses ESLint and Prettier)
|
|
323
276
|
|
|
324
|
-
## License
|
|
325
|
-
|
|
326
|
-
[](https://opensource.org/licenses/MIT)
|
|
327
|
-
|
|
328
|
-
Citadel is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
|
329
|
-
|
|
330
|
-
This means you can use Citadel in your own projects (commercial or non-commercial) as long as you include the original copyright notice and license terms. The MIT License is simple and permissive, allowing you to:
|
|
331
|
-
|
|
332
|
-
- Use the code commercially
|
|
333
|
-
- Modify the code
|
|
334
|
-
- Distribute the code
|
|
335
|
-
- Use in private/closed-source projects
|
|
336
|
-
|
|
337
|
-
All we ask is that you include the original license and copyright notice in any copy or substantial portion of the software.
|
package/dist/App.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { CommandNode, CommandRegistry, CommandHandler, CommandSegment } from '../components/Citadel/types/command-registry';
|
|
2
|
+
import { CitadelState, CitadelActions, OutputItem } from '../components/Citadel/types';
|
|
3
|
+
import { SegmentStack } from '../components/Citadel/types/segment-stack';
|
|
4
|
+
import { CommandHistory, CommandHistoryActions } from '../components/Citadel/hooks/useCommandHistory';
|
|
5
|
+
import { StoredCommand } from '../components/Citadel/types/storage';
|
|
6
|
+
interface MockNodeOptions {
|
|
7
|
+
handler?: CommandHandler;
|
|
8
|
+
description?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const createMockSegment: (type: "word" | "argument" | "null", name?: string, description?: string) => CommandSegment;
|
|
11
|
+
export declare const createMockCommandSegment: (type: "word" | "argument", name: string, description?: string) => CommandSegment;
|
|
12
|
+
export declare const createMockCommand: (name: string, options?: MockNodeOptions) => CommandNode;
|
|
13
|
+
export declare const createMockCommandRegistry: () => CommandRegistry;
|
|
14
|
+
export declare const createMockStoredCommand: (overrides?: {}) => StoredCommand;
|
|
15
|
+
export declare const createMockStorage: () => {
|
|
16
|
+
addStoredCommand: import('vitest').Mock<(...args: any[]) => any>;
|
|
17
|
+
getStoredCommands: import('vitest').Mock<(...args: any[]) => any>;
|
|
18
|
+
clear: import('vitest').Mock<(...args: any[]) => any>;
|
|
19
|
+
};
|
|
20
|
+
export declare const createMockCommandHistory: (overrides?: {}) => CommandHistory;
|
|
21
|
+
export declare const createMockCommandHistoryActions: (overrides?: {}) => CommandHistoryActions;
|
|
22
|
+
export declare const createMockCitadelState: (overrides?: {}) => CitadelState;
|
|
23
|
+
export declare const createMockOutputItem: (command?: string[]) => OutputItem;
|
|
24
|
+
export declare const setupCitadelStateHook: () => {
|
|
25
|
+
hook: import('@testing-library/react').RenderHookResult<{
|
|
26
|
+
state: CitadelState;
|
|
27
|
+
actions: CitadelActions;
|
|
28
|
+
getAvailableCommands_s: () => string[];
|
|
29
|
+
getAvailableCommandSegments: () => CommandSegment[];
|
|
30
|
+
}, unknown>;
|
|
31
|
+
mockHistory: CommandHistory;
|
|
32
|
+
mockActions: CommandHistoryActions;
|
|
33
|
+
mockCommands: CommandRegistry;
|
|
34
|
+
mockStack: SegmentStack;
|
|
35
|
+
};
|
|
36
|
+
export declare const createMockCitadelActions: (overrides?: {}) => CitadelActions;
|
|
37
|
+
export declare const createMockSegmentStack: () => SegmentStack;
|
|
38
|
+
export declare const createMockKeyboardEvent: (key: string) => KeyboardEvent;
|
|
39
|
+
export declare const createTestCommand: (path: string[], description?: string, handler?: CommandHandler) => CommandNode;
|
|
40
|
+
export {};
|
package/dist/citadel.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
._container_141sr_3{position:fixed;height:var(--citadel-default-height);min-height:var(--citadel-min-height);max-height:var(--citadel-max-height);background-color:var(--citadel-bg);overflow:hidden;width:100%;box-sizing:border-box;margin:0;padding:0;bottom:0;left:0;right:0}._innerContainer_141sr_19{height:100%;width:100%;display:flex;flex-direction:column;margin:0;padding:0}._inputSection_141sr_28{border-top:1px solid var(--citadel-border);padding:1rem;margin:0;box-sizing:border-box}._resizeHandle_141sr_35{width:100%;height:6px;background:transparent;cursor:ns-resize;position:absolute;top:-3px;left:0;right:0;z-index:10;-moz-user-select:none;user-select:none;-webkit-user-select:none;pointer-events:all}._resizeHandle_141sr_35:hover{background:#ffffff1a}@keyframes _citadel_slideUp_141sr_64{0%{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes _citadel_slideDown_141sr_68{0%{transform:translateY(0)}to{transform:translateY(100%)}}._citadel_slideUp_141sr_64{animation:_citadel_slideUp_141sr_64 .2s ease-out forwards}._citadel_slideDown_141sr_68{animation:_citadel_slideDown_141sr_68 .2s ease-out forwards}
|
|
1
|
+
._container_141sr_3{position:fixed;height:var(--citadel-default-height);min-height:var(--citadel-min-height);max-height:var(--citadel-max-height);background-color:var(--citadel-bg);overflow:hidden;width:100%;box-sizing:border-box;margin:0;padding:0;bottom:0;left:0;right:0}._innerContainer_141sr_19{height:100%;width:100%;display:flex;flex-direction:column;margin:0;padding:0}._inputSection_141sr_28{border-top:1px solid var(--citadel-border);padding:1rem;margin:0;box-sizing:border-box}._resizeHandle_141sr_35{width:100%;height:6px;background:transparent;cursor:ns-resize;position:absolute;top:-3px;left:0;right:0;z-index:10;-moz-user-select:none;user-select:none;-webkit-user-select:none;pointer-events:all}._resizeHandle_141sr_35:hover{background:#ffffff1a}@keyframes _citadel_slideUp_141sr_64{0%{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes _citadel_slideDown_141sr_68{0%{transform:translateY(0)}to{transform:translateY(100%)}}._citadel_slideUp_141sr_64{animation:_citadel_slideUp_141sr_64 .2s ease-out forwards}._citadel_slideDown_141sr_68{animation:_citadel_slideDown_141sr_68 .2s ease-out forwards}
|