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.
Files changed (73) hide show
  1. package/README.md +149 -210
  2. package/dist/App.d.ts +2 -0
  3. package/dist/__test-utils__/factories.d.ts +40 -0
  4. package/dist/citadel.css +1 -1
  5. package/dist/citadel.es.js +1271 -1418
  6. package/dist/citadel.umd.js +34 -19
  7. package/dist/components/Citadel/Citadel.d.ts +15 -0
  8. package/dist/components/Citadel/components/AvailableCommands.d.ts +2 -0
  9. package/dist/{src/components → components}/Citadel/components/CommandInput.d.ts +0 -2
  10. package/dist/components/Citadel/config/CitadelConfigContext.d.ts +18 -0
  11. package/dist/{src/components → components}/Citadel/config/defaults.d.ts +15 -7
  12. package/dist/components/Citadel/config/hooks.d.ts +4 -0
  13. package/dist/{src/components → components}/Citadel/config/types.d.ts +32 -20
  14. package/dist/{src/components → components}/Citadel/hooks/useCitadelState.d.ts +2 -1
  15. package/dist/components/Citadel/hooks/useCommandHistory.d.ts +27 -0
  16. package/dist/components/Citadel/hooks/useCommandParser.d.ts +22 -0
  17. package/dist/components/Citadel/hooks/useSegmentStack.d.ts +14 -0
  18. package/dist/components/Citadel/hooks/useSegmentStackVersion.d.ts +1 -0
  19. package/dist/{src/components → components}/Citadel/storage/BaseStorage.d.ts +2 -2
  20. package/dist/{src/components → components}/Citadel/storage/LocalStorage.d.ts +1 -1
  21. package/dist/{src/components → components}/Citadel/storage/MemoryStorage.d.ts +2 -2
  22. package/dist/components/Citadel/types/command-registry.d.ts +88 -0
  23. package/dist/{src/components → components}/Citadel/types/command-results.d.ts +2 -2
  24. package/dist/components/Citadel/types/help-command.d.ts +3 -0
  25. package/dist/components/Citadel/types/segment-stack.d.ts +62 -0
  26. package/dist/{src/components → components}/Citadel/types/state.d.ts +8 -22
  27. package/dist/{src/components → components}/Citadel/types/storage.d.ts +4 -3
  28. package/dist/components/Citadel/utils/logger.d.ts +21 -0
  29. package/dist/index.d.ts +4 -2
  30. package/package.json +12 -5
  31. package/dist/command_examples/basic-commands.d.ts +0 -83
  32. package/dist/dist/styles.css +0 -789
  33. package/dist/src/App.d.ts +0 -4
  34. package/dist/src/__test-utils__/factories.d.ts +0 -21
  35. package/dist/src/components/Citadel/Citadel.d.ts +0 -11
  36. package/dist/src/components/Citadel/commands/history-commands.d.ts +0 -2
  37. package/dist/src/components/Citadel/components/AvailableCommands.d.ts +0 -9
  38. package/dist/src/components/Citadel/config/CitadelConfigContext.d.ts +0 -11
  39. package/dist/src/components/Citadel/hooks/useCommandHistory.d.ts +0 -17
  40. package/dist/src/components/Citadel/hooks/useCommandParser.d.ts +0 -19
  41. package/dist/src/components/Citadel/hooks/useCommandTrie.d.ts +0 -2
  42. package/dist/src/components/Citadel/types/command-context.d.ts +0 -4
  43. package/dist/src/components/Citadel/types/command-trie.d.ts +0 -238
  44. package/dist/src/components/Citadel/types/help-command.d.ts +0 -3
  45. package/dist/src/components/Citadel/utils/keySimulation.d.ts +0 -2
  46. package/dist/src/index.d.ts +0 -4
  47. /package/dist/{src/components → components}/Citadel/Cursor.d.ts +0 -0
  48. /package/dist/{src/components → components}/Citadel/__tests__/Citadel.test.d.ts +0 -0
  49. /package/dist/{src/components → components}/Citadel/components/CommandOutput.d.ts +0 -0
  50. /package/dist/{src/components → components}/Citadel/components/CommandOutputLine.d.ts +0 -0
  51. /package/dist/{src/components → components}/Citadel/components/Spinner.d.ts +0 -0
  52. /package/dist/{src/components → components}/Citadel/components/__tests__/AvailableCommands.test.d.ts +0 -0
  53. /package/dist/{src/components → components}/Citadel/components/__tests__/CommandInput.test.d.ts +0 -0
  54. /package/dist/{src/components → components}/Citadel/components/__tests__/CommandOutput.test.d.ts +0 -0
  55. /package/dist/{src/components → components}/Citadel/components/__tests__/CommandOutputLine.test.d.ts +0 -0
  56. /package/dist/{src/components → components}/Citadel/components/__tests__/Spinner.test.d.ts +0 -0
  57. /package/dist/{src/components → components}/Citadel/config/__tests__/CitadelConfigContext.test.d.ts +0 -0
  58. /package/dist/{src/components → components}/Citadel/hooks/__tests__/useCitadelState.test.d.ts +0 -0
  59. /package/dist/{src/components → components}/Citadel/hooks/__tests__/useCommandHistory.test.d.ts +0 -0
  60. /package/dist/{src/components → components}/Citadel/hooks/__tests__/useCommandParser.test.d.ts +0 -0
  61. /package/dist/{src/components → components}/Citadel/hooks/useGlobalShortcut.d.ts +0 -0
  62. /package/dist/{src/components → components}/Citadel/hooks/useSlideAnimation.d.ts +0 -0
  63. /package/dist/{src/components → components}/Citadel/index.d.ts +0 -0
  64. /package/dist/{src/components → components}/Citadel/services/HistoryService.d.ts +0 -0
  65. /package/dist/{src/components → components}/Citadel/storage/StorageFactory.d.ts +0 -0
  66. /package/dist/{src/components → components}/Citadel/storage/__tests__/LocalStorage.test.d.ts +0 -0
  67. /package/dist/{src/components → components}/Citadel/storage/__tests__/MemoryStorage.test.d.ts +0 -0
  68. /package/dist/{src/components/Citadel/hooks/__tests__/useCommandTrie.test.d.ts → components/Citadel/types/__tests__/command-registry.test.d.ts} +0 -0
  69. /package/dist/{src/components/Citadel/types/__tests__/command-trie.test.d.ts → components/Citadel/types/__tests__/segment-stack.test.d.ts} +0 -0
  70. /package/dist/{src/components → components}/Citadel/types/cursor.d.ts +0 -0
  71. /package/dist/{src/components → components}/Citadel/types/index.d.ts +0 -0
  72. /package/dist/{src/main.d.ts → main.d.ts} +0 -0
  73. /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
- A hierarchical command-line interface (CLI) for web applications.
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
+ ![Animated screenshot of Citadel CLI](https://github.com/user-attachments/assets/b64da0f7-a4a0-4f76-bc03-c0e40c0e14e5)
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
- // Mount in your React app
28
+ import { Citadel } from "citadel_cli";
29
+
24
30
  function App() {
25
31
  return (
26
- <div>
27
- <Citadel commands={commands} />
28
- {/* Your app content */}
29
- </div>
32
+ <>
33
+ <Citadel />
34
+ </>
30
35
  );
31
36
  }
32
37
  ```
33
38
 
34
- ## Command Usage
39
+ Press <kbd>.</kbd> (period) to activate Citadel.
35
40
 
36
- Citadel commands composed of one or more words followed by zero or one arguments. For example:
37
- ```
38
- > ticket new customer 1234
39
- ```
40
- Where the user typed "tnc1234" to achieve the above result.
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
+ ![screenshot_help_cmd](https://github.com/user-attachments/assets/1cc6fd58-7591-45f1-980a-46da15a1843a)
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
- ### Quick Execution
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
- ticket new → tn
48
- deploy status → ds
49
- customer history → ch
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
- Simply type the first letter of each word in the command and press Enter.
82
+ Word segments are autocompleted, whereas argument segments are used to store
83
+ user-entered values.
53
84
 
54
- ### Arguments
85
+ A few notes on arguments:
55
86
 
56
- Commands can have zero or more arguments.
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
- ```bash
59
- > ticket new customer 1234
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
- ### JavaScript Integration
100
+ ```
101
+ async (args: string[]) => new TextCommandResult(`Hello, ${args[0]}!`)
102
+ ```
63
103
 
64
- Commands can execute any JavaScript code, making them powerful automation tools:
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
- ```typescript
67
- commands.addCommand(
68
- ['refresh', 'cache'],
69
- 'Refresh application cache',
70
- async () => {
71
- // Clear local storage
109
+ ```
110
+ async (_args: string[]) => {
72
111
  localStorage.clear();
73
- // Reset Redux store
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
- ### Dynamic Results
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
- ```typescript
91
- commands.addCommand(
92
- ['user', 'activity'],
93
- 'Show user activity',
94
- async (args) => ({
95
- // Return both data and visualization
96
- json: await getUserActivity(args.userId),
97
- component: <ActivityGraph userId={args.userId} />
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
- ## Real-World Examples
131
+ At the time of this writing the following command result types are available:
103
132
 
104
- ### Customer Service Application
133
+ - `ErrorCommandResult`
134
+ - `ImageCommandResult`
135
+ - `JsonCommandResult`
136
+ - `TextCommandResult`
105
137
 
106
- ```typescript
107
- // Customer service command configuration
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
- ### Trading Platform Integration
144
+ const cmdRegistry = new CommandRegistry();
142
145
 
143
- ```typescript
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
- { name: 'pair', description: 'Trading pair (e.g., btc-usd)' },
159
- { name: 'price', description: 'Limit price' },
160
- { name: 'quantity', description: 'Order quantity' },
161
- { name: 'side', description: 'Order side (buy|sell)' }
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
- ### DevOps Dashboard Commands
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
- ## Advanced Configuration
162
+ The result of this should look like this:
202
163
 
203
- ### Custom Command Rendering
164
+ ![screenshot_greeting_cmd](https://github.com/user-attachments/assets/a3c1acad-69b3-4079-87af-0425aea3980a)
204
165
 
205
- Citadel supports custom rendering of command results:
166
+ Go forth and make your application experience better!
206
167
 
207
- ```typescript
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
- ### Authentication Integration
170
+ Certain configuration options can be passed to the Citadel component. These are
171
+ given below, along with their default values.
220
172
 
221
- ```typescript
222
- const citadelConfig = {
223
- commandFilter: (command) => {
224
- const userPermissions = getUserPermissions();
225
- return command.requiredPermissions.every(
226
- (perm) => userPermissions.includes(perm)
227
- );
228
- },
229
- // ... other config
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
- ## Development
192
+ Then to make the component aware of them:
234
193
 
235
- ### Project Structure
236
194
  ```
237
- citadel/
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
- ### Contributing
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/citadel.git
254
- cd citadel
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 @jchilders/citadel
275
- # ... your normal build/run steps ...
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
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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,2 @@
1
+ declare function App(): import("react/jsx-runtime").JSX.Element;
2
+ export default App;
@@ -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}@keyframes _shake_e9b9w_1{0%,to{transform:translate(0)}25%{transform:translate(-4px)}75%{transform:translate(4px)}}@keyframes _flashBorder_e9b9w_1{0%,to{border-color:transparent}50%{border-color:#ef4444}}._invalidInput_e9b9w_12{animation:_shake_e9b9w_1 .2s ease-in-out,_flashBorder_e9b9w_1 .3s ease-in-out;border-width:1px;border-style:solid}
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}