citadel_cli 1.0.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/LICENSE +21 -0
- package/README.md +337 -0
- package/dist/.vite/manifest.json +12 -0
- package/dist/citadel.css +1 -0
- package/dist/citadel.es.js +3039 -0
- package/dist/citadel.umd.js +1015 -0
- package/dist/command_examples/basic-commands.d.ts +83 -0
- package/dist/dist/styles.css +789 -0
- package/dist/index.d.ts +2 -0
- package/dist/src/App.d.ts +4 -0
- package/dist/src/__test-utils__/factories.d.ts +21 -0
- package/dist/src/components/Citadel/Citadel.d.ts +11 -0
- package/dist/src/components/Citadel/Cursor.d.ts +9 -0
- package/dist/src/components/Citadel/__tests__/Citadel.test.d.ts +1 -0
- package/dist/src/components/Citadel/commands/history-commands.d.ts +2 -0
- package/dist/src/components/Citadel/components/AvailableCommands.d.ts +9 -0
- package/dist/src/components/Citadel/components/CommandInput.d.ts +10 -0
- package/dist/src/components/Citadel/components/CommandOutput.d.ts +8 -0
- package/dist/src/components/Citadel/components/CommandOutputLine.d.ts +9 -0
- package/dist/src/components/Citadel/components/Spinner.d.ts +2 -0
- package/dist/src/components/Citadel/components/__tests__/AvailableCommands.test.d.ts +1 -0
- package/dist/src/components/Citadel/components/__tests__/CommandInput.test.d.ts +1 -0
- package/dist/src/components/Citadel/components/__tests__/CommandOutput.test.d.ts +1 -0
- package/dist/src/components/Citadel/components/__tests__/CommandOutputLine.test.d.ts +1 -0
- package/dist/src/components/Citadel/components/__tests__/Spinner.test.d.ts +1 -0
- package/dist/src/components/Citadel/config/CitadelConfigContext.d.ts +11 -0
- package/dist/src/components/Citadel/config/__tests__/CitadelConfigContext.test.d.ts +1 -0
- package/dist/src/components/Citadel/config/defaults.d.ts +26 -0
- package/dist/src/components/Citadel/config/types.d.ts +56 -0
- package/dist/src/components/Citadel/hooks/__tests__/useCitadelState.test.d.ts +1 -0
- package/dist/src/components/Citadel/hooks/__tests__/useCommandHistory.test.d.ts +1 -0
- package/dist/src/components/Citadel/hooks/__tests__/useCommandParser.test.d.ts +1 -0
- package/dist/src/components/Citadel/hooks/__tests__/useCommandTrie.test.d.ts +1 -0
- package/dist/src/components/Citadel/hooks/useCitadelState.d.ts +6 -0
- package/dist/src/components/Citadel/hooks/useCommandHistory.d.ts +17 -0
- package/dist/src/components/Citadel/hooks/useCommandParser.d.ts +19 -0
- package/dist/src/components/Citadel/hooks/useCommandTrie.d.ts +2 -0
- package/dist/src/components/Citadel/hooks/useGlobalShortcut.d.ts +8 -0
- package/dist/src/components/Citadel/hooks/useSlideAnimation.d.ts +14 -0
- package/dist/src/components/Citadel/index.d.ts +2 -0
- package/dist/src/components/Citadel/services/HistoryService.d.ts +15 -0
- package/dist/src/components/Citadel/storage/BaseStorage.d.ts +25 -0
- package/dist/src/components/Citadel/storage/LocalStorage.d.ts +12 -0
- package/dist/src/components/Citadel/storage/MemoryStorage.d.ts +12 -0
- package/dist/src/components/Citadel/storage/StorageFactory.d.ts +9 -0
- package/dist/src/components/Citadel/storage/__tests__/LocalStorage.test.d.ts +1 -0
- package/dist/src/components/Citadel/storage/__tests__/MemoryStorage.test.d.ts +1 -0
- package/dist/src/components/Citadel/types/__tests__/command-trie.test.d.ts +1 -0
- package/dist/src/components/Citadel/types/command-context.d.ts +4 -0
- package/dist/src/components/Citadel/types/command-results.d.ts +41 -0
- package/dist/src/components/Citadel/types/command-trie.d.ts +238 -0
- package/dist/src/components/Citadel/types/cursor.d.ts +26 -0
- package/dist/src/components/Citadel/types/help-command.d.ts +3 -0
- package/dist/src/components/Citadel/types/index.d.ts +3 -0
- package/dist/src/components/Citadel/types/state.d.ts +40 -0
- package/dist/src/components/Citadel/types/storage.d.ts +44 -0
- package/dist/src/components/Citadel/utils/keySimulation.d.ts +2 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/main.d.ts +1 -0
- package/dist/src/test/setup.d.ts +1 -0
- package/package.json +73 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 James Childers
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
# Citadel
|
|
2
|
+
|
|
3
|
+
A hierarchical command-line interface (CLI) for web applications.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```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
|
+
|
|
23
|
+
// Mount in your React app
|
|
24
|
+
function App() {
|
|
25
|
+
return (
|
|
26
|
+
<div>
|
|
27
|
+
<Citadel commands={commands} />
|
|
28
|
+
{/* Your app content */}
|
|
29
|
+
</div>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Command Usage
|
|
35
|
+
|
|
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
|
+
|
|
42
|
+
|
|
43
|
+
### Quick Execution
|
|
44
|
+
|
|
45
|
+
Commands can be typed using abbreviated forms. For example:
|
|
46
|
+
```
|
|
47
|
+
ticket new → tn
|
|
48
|
+
deploy status → ds
|
|
49
|
+
customer history → ch
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Simply type the first letter of each word in the command and press Enter.
|
|
53
|
+
|
|
54
|
+
### Arguments
|
|
55
|
+
|
|
56
|
+
Commands can have zero or more arguments.
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
> ticket new customer 1234
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### JavaScript Integration
|
|
63
|
+
|
|
64
|
+
Commands can execute any JavaScript code, making them powerful automation tools:
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
commands.addCommand(
|
|
68
|
+
['refresh', 'cache'],
|
|
69
|
+
'Refresh application cache',
|
|
70
|
+
async () => {
|
|
71
|
+
// Clear local storage
|
|
72
|
+
localStorage.clear();
|
|
73
|
+
// Reset Redux store
|
|
74
|
+
store.dispatch(resetState());
|
|
75
|
+
// Reload application
|
|
76
|
+
window.location.reload();
|
|
77
|
+
return { json: { status: 'Cache cleared' } };
|
|
78
|
+
}
|
|
79
|
+
);
|
|
80
|
+
```
|
|
81
|
+
|
|
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
|
|
89
|
+
|
|
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
|
+
);
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Real-World Examples
|
|
103
|
+
|
|
104
|
+
### Customer Service Application
|
|
105
|
+
|
|
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
|
+
);
|
|
125
|
+
|
|
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
|
+
```
|
|
140
|
+
|
|
141
|
+
### Trading Platform Integration
|
|
142
|
+
|
|
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
|
+
},
|
|
157
|
+
[
|
|
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
|
+
]
|
|
163
|
+
);
|
|
164
|
+
```
|
|
165
|
+
|
|
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
|
+
);
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Advanced Configuration
|
|
202
|
+
|
|
203
|
+
### Custom Command Rendering
|
|
204
|
+
|
|
205
|
+
Citadel supports custom rendering of command results:
|
|
206
|
+
|
|
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
|
+
```
|
|
218
|
+
|
|
219
|
+
### Authentication Integration
|
|
220
|
+
|
|
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
|
|
230
|
+
};
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Development
|
|
234
|
+
|
|
235
|
+
### Project Structure
|
|
236
|
+
```
|
|
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
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Contributing
|
|
248
|
+
|
|
249
|
+
Contributions are welcome.
|
|
250
|
+
|
|
251
|
+
1. Clone the repository:
|
|
252
|
+
```bash
|
|
253
|
+
git clone https://github.com/jchilders/citadel.git
|
|
254
|
+
cd citadel
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
2. Install dependencies:
|
|
258
|
+
```bash
|
|
259
|
+
npm install
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
3. Build the package:
|
|
263
|
+
```bash
|
|
264
|
+
npm run build
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
4. (Optional but recommended) Link citadel so you can import it into a parallel project
|
|
268
|
+
```bash
|
|
269
|
+
npm link
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
5. (Optional) From the directory of the project you want to import Citadel into:
|
|
273
|
+
```bash
|
|
274
|
+
npm link @jchilders/citadel
|
|
275
|
+
# ... your normal build/run steps ...
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Bug Reports and Feature Requests
|
|
279
|
+
|
|
280
|
+
- Use the GitHub Issues section to report bugs or suggest features
|
|
281
|
+
- Before creating a new issue, please check if a similar issue already exists
|
|
282
|
+
- Provide as much detail as possible in bug reports:
|
|
283
|
+
- Steps to reproduce the issue
|
|
284
|
+
- Expected behavior
|
|
285
|
+
- Actual behavior
|
|
286
|
+
- Browser/environment information
|
|
287
|
+
- Error messages or screenshots if applicable
|
|
288
|
+
|
|
289
|
+
### Development Process
|
|
290
|
+
|
|
291
|
+
1. Fork the repository
|
|
292
|
+
2. Create a new branch for your feature or bugfix:
|
|
293
|
+
```bash
|
|
294
|
+
git checkout -b feature/your-feature-name
|
|
295
|
+
# or
|
|
296
|
+
git checkout -b fix/your-bugfix-name
|
|
297
|
+
```
|
|
298
|
+
3. Make your changes
|
|
299
|
+
4. Write or update tests as needed
|
|
300
|
+
5. Run the test suite to ensure everything passes:
|
|
301
|
+
```bash
|
|
302
|
+
npm test
|
|
303
|
+
```
|
|
304
|
+
6. Commit your changes with a clear and descriptive commit message
|
|
305
|
+
7. Push to your fork and submit a pull request
|
|
306
|
+
|
|
307
|
+
### Pull Request Guidelines
|
|
308
|
+
|
|
309
|
+
- Keep your changes focused. Submit separate pull requests for separate features/fixes
|
|
310
|
+
- Follow the existing code style and conventions
|
|
311
|
+
- Include tests for new functionality
|
|
312
|
+
- Update documentation as needed
|
|
313
|
+
- Ensure all tests pass
|
|
314
|
+
- Describe your changes in detail in the pull request description
|
|
315
|
+
|
|
316
|
+
### Code Style
|
|
317
|
+
|
|
318
|
+
- Follow TypeScript best practices
|
|
319
|
+
- Use meaningful variable and function names
|
|
320
|
+
- Comment complex logic or non-obvious code
|
|
321
|
+
- Keep functions focused and modular
|
|
322
|
+
- Use consistent formatting (the project uses ESLint and Prettier)
|
|
323
|
+
|
|
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/citadel.css
ADDED
|
@@ -0,0 +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}
|