citadel_cli 1.1.7 → 1.4.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/README.md CHANGED
@@ -24,31 +24,27 @@ npm i citadel_cli
24
24
  A core concept in Citadel are commands. Commands are things like "user add 1234"
25
25
  or "qa1 deploy my_feature_branch". To initialize and add commands:
26
26
 
27
- 1. Create a `CommandRegistry` instance
28
- 2. Add one or more commands to that registry
27
+ 1. Define commands with the typed DSL
28
+ 2. Build a `CommandRegistry` from those definitions
29
29
  3. Pass the registry to `Citadel`
30
30
 
31
31
  ```typescript
32
32
  import {
33
33
  Citadel,
34
- CommandRegistry,
35
- TextCommandResult,
34
+ command,
35
+ createCommandRegistry,
36
+ text,
36
37
  } from "citadel_cli";
37
38
 
38
- // 1. Create the registry
39
- const registry = new CommandRegistry();
39
+ // 1. Define and register commands
40
+ const registry = createCommandRegistry([
41
+ command("greet")
42
+ .describe("Say hello to someone")
43
+ .arg("name", (arg) => arg.describe("Who are we greeting?"))
44
+ .handle(async ({ namedArgs }) => text(`Hello ${namedArgs.name} world!`)),
45
+ ]);
40
46
 
41
- // 2. Add commands
42
- registry.addCommand(
43
- [
44
- { type: "word", name: "greet" },
45
- { type: "argument", name: "name", description: "Who are we greeting?" },
46
- ],
47
- "Say hello to someone", // Description used by the built-in `help` command
48
- async (args: string[]) => new TextCommandResult(`Hello ${args[0]} world!`)
49
- );
50
-
51
- // 3. Pass the registry to the component
47
+ // 2. Pass the registry to the component
52
48
  function App() {
53
49
  return <Citadel commandRegistry={registry} />;
54
50
  }
@@ -64,28 +60,68 @@ to the full word. For the above example, typing <kbd>g</kbd> would expand
64
60
  in-place to `greet ` (with a trailing space) whereupon you can enter in a value
65
61
  for the `name` argument.
66
62
 
67
- ## `addCommand` Details
63
+ For hierarchical commands, expansion is prefix-based and unambiguous:
68
64
 
69
- The `addCommand` method has the following signature:
65
+ - `us` can resolve to `user show`
66
+ - `ud` can resolve to `user deactivate`
67
+ - If two options share a prefix (`show` and `search`), continue until unique:
68
+ `ush` => `user show`, `use` => `user search`
70
69
 
71
- ```typescript
72
- addCommand(segments: CommandSegment[], description: string, handler: CommandHandler): void
73
- ```
70
+ ## Help Text
74
71
 
75
- `segments[]` - Each `CommandSegment` in this array consists of a `type` (one of
76
- "word" or "argument"), a `name`, and an optional `description`
72
+ Argument segment `description` values are shown as argument-level help text.
73
+ Example built-in help output:
77
74
 
78
- `description` - Description of the command itself. Used by the built-in help
79
- command
75
+ ```text
76
+ user show <userId> - Show user details
77
+ <userId>: Enter user ID
78
+ ```
80
79
 
81
- `handler` - What gets executed when <kbd>Enter</kbd> is pressed. The handler
82
- must return one of the following:
80
+ Handlers must return one of the following:
83
81
 
84
82
  - `TextCommandResult`
85
83
  - `JsonCommandResult`
86
84
  - `ImageCommandResult`
87
85
  - `ErrorCommandResult`
88
86
 
87
+ ## Typed DSL
88
+
89
+ For clearer command authoring, you can define commands with a DSL and compile
90
+ them into a `CommandRegistry`:
91
+
92
+ ```typescript
93
+ import {
94
+ Citadel,
95
+ command,
96
+ createCommandRegistry,
97
+ text,
98
+ } from "citadel_cli";
99
+
100
+ const registry = createCommandRegistry([
101
+ command("user.show")
102
+ .describe("Show user details")
103
+ .arg("userId", (arg) => arg.describe("Enter user ID"))
104
+ .handle(async ({ namedArgs }) => {
105
+ return text(`Showing user ${namedArgs.userId}`);
106
+ }),
107
+ ]);
108
+
109
+ function App() {
110
+ return <Citadel commandRegistry={registry} />;
111
+ }
112
+ ```
113
+
114
+ DSL handlers receive:
115
+
116
+ - `rawArgs`: positional values (`string[]`)
117
+ - `namedArgs`: argument-name map (`Record<string, string | undefined>`)
118
+ - `commandPath`: dot-delimited path string
119
+
120
+ ## Legacy `addCommand` API
121
+
122
+ `CommandRegistry#addCommand` still works and is fully supported. The DSL is now
123
+ the recommended authoring path for new command definitions.
124
+
89
125
  ### Arguments
90
126
 
91
127
  1. Each command can have zero or more arguments
@@ -128,10 +164,12 @@ given below, along with their default values.
128
164
  const config = {
129
165
  commandTimeoutMs: 10000,
130
166
  includeHelpCommand: true,
167
+ fontFamily: '"JetBrains Mono", monospace',
168
+ fontSize: '0.875rem', // CSS font-size value (e.g. '14px', '0.875rem')
131
169
  maxHeight: '80vh',
132
- initialHeight: '40vh',
170
+ initialHeight: '50vh',
133
171
  minHeight: '200',
134
- outputFontSize: '0.875rem',
172
+ outputFontSize: '0.75rem', // optional CSS font-size override for output text
135
173
  resetStateOnHide: false,
136
174
  showCitadelKey: '.',
137
175
  cursorType: 'blink', // 'blink', 'spin', 'solid', or 'bbs'
@@ -149,6 +187,64 @@ Then to make the component aware of them:
149
187
  <Citadel commandRegistry={cmdRegistry} config={config} />
150
188
  ```
151
189
 
190
+ ## Performance Metrics
191
+
192
+ Citadel includes scripts to capture and compare before/after performance and
193
+ size metrics.
194
+
195
+ ### Metrics collected
196
+
197
+ - Build metrics:
198
+ - Bundle size (raw + gzip) for `dist/citadel.es.js`, `dist/citadel.umd.cjs`,
199
+ and `dist/citadel.css`
200
+ - Total LOC and extension breakdown
201
+ - Dependency presence for `tailwindcss`, `postcss`, and `autoprefixer`
202
+ - `node_modules` size (`du -sk`)
203
+ - Runtime metrics (Chromium):
204
+ - JS heap usage before/after interaction
205
+ - Input latency (keydown to input update)
206
+ - FPS sample over a short window
207
+ - Long task count and duration
208
+ - DOM node count
209
+
210
+ All outputs are written to `test-results/metrics/`.
211
+
212
+ ### Commands
213
+
214
+ ```bash
215
+ npm run metrics:build
216
+ npm run metrics:runtime
217
+ npm run metrics:compare -- --before <before.json> --after <after.json>
218
+ npm run metrics:all -- --label <label>
219
+ npm run metrics:report -- --label <label> --before-build <before-build.json> --before-runtime <before-runtime.json>
220
+ ```
221
+
222
+ ### Before/After workflow
223
+
224
+ 1. Capture a baseline snapshot:
225
+
226
+ ```bash
227
+ npm run metrics:all -- --label before
228
+ ```
229
+
230
+ 2. After your changes, capture the new snapshot and generate comparisons:
231
+
232
+ ```bash
233
+ npm run metrics:all -- --label after \
234
+ --before-build test-results/metrics/build-before-<timestamp>.json \
235
+ --before-runtime test-results/metrics/runtime-before-<timestamp>.json
236
+ ```
237
+
238
+ 3. Open generated reports:
239
+ - `test-results/metrics/run-after.md`
240
+ - `test-results/metrics/compare-build-after.md` (if `--before-build` provided)
241
+ - `test-results/metrics/compare-runtime-after.md` (if `--before-runtime` provided)
242
+
243
+ Notes:
244
+ - `metrics:runtime` starts a local dev server and requires local port binding.
245
+ - If you only want comparison output from existing snapshots, use
246
+ `npm run metrics:report`.
247
+
152
248
  ## Contributing
153
249
 
154
250
  See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines on developing, testing, and releasing Citadel CLI.
@@ -4,9 +4,5 @@
4
4
  "name": "index",
5
5
  "src": "src/index.ts",
6
6
  "isEntry": true
7
- },
8
- "style.css": {
9
- "file": "citadel.css",
10
- "src": "style.css"
11
7
  }
12
8
  }