@silvery/commander 0.6.0 → 0.6.1

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 (3) hide show
  1. package/README.md +34 -24
  2. package/package.json +3 -5
  3. package/src/colorize.ts +12 -26
package/README.md CHANGED
@@ -12,44 +12,54 @@ npm install @silvery/commander
12
12
  import { Command, z } from "@silvery/commander"
13
13
 
14
14
  const program = new Command("deploy")
15
- .description("Deploy to an environment")
15
+ .description("Deploy services to an environment")
16
16
  .version("1.0.0")
17
17
  .option("-e, --env <env>", "Target environment", z.enum(["dev", "staging", "prod"]))
18
+ .option("-f, --force", "Skip confirmation")
19
+ .option("-v, --verbose", "Verbose output")
20
+
21
+ program
22
+ .command("start <service>")
23
+ .description("Start a service")
18
24
  .option("-p, --port <n>", "Port number", z.port)
19
25
  .option("-r, --retries <n>", "Retry count", z.int)
20
- .option("--tags <t>", "Labels", z.csv)
21
- .option("-f, --force", "Skip confirmation")
26
+ .action((service, opts) => {
27
+ /* ... */
28
+ })
29
+
30
+ program
31
+ .command("stop <service>")
32
+ .description("Stop a running service")
33
+ .action((service) => {
34
+ /* ... */
35
+ })
36
+
37
+ program
38
+ .command("status")
39
+ .description("Show service status")
40
+ .option("--json", "Output as JSON")
41
+ .action((opts) => {
42
+ /* ... */
43
+ })
22
44
 
23
45
  program.parse()
24
- const { env, port, retries, tags, force } = program.opts()
25
- // │└─ boolean | undefined
26
- // │ │ └──────── string[]
27
- // │ │ └────────────────── number
28
- // │ └──────────────────────── number (1–65535)
29
- // └─────────────────────────────── "dev" | "staging" | "prod"
46
+ const { env, force, verbose } = program.opts()
47
+ // │ │ └─ boolean | undefined
48
+ // │ └────────── boolean | undefined
49
+ // └──────────────── "dev" | "staging" | "prod"
30
50
  ```
31
51
 
32
52
  With plain Commander, `opts()` returns `Record<string, any>` — every value is untyped. With `@silvery/commander`, each option's type is inferred from its schema: `z.port` produces `number`, `z.enum(...)` produces a union, `z.csv` produces `string[]`. Invalid values are rejected at parse time with clear error messages — not silently passed through as strings.
33
53
 
34
54
  [Zod](https://github.com/colinhacks/zod) is entirely optional — `z` is tree-shaken from your bundle if you don't import it. Without Zod, use the built-in types (`port`, `int`, `csv`) or plain Commander.
35
55
 
36
- <pre><code>$ deploy --help
37
-
38
- <b>Usage:</b> <span style="color:#56b6c2">deploy</span> <span style="color:#98c379">[options]</span>
39
-
40
- Deploy to an environment
56
+ Help is auto-colorized — bold headings, green flags, cyan commands, dim descriptions:
41
57
 
42
- <b>Options:</b>
43
- <span style="color:#98c379">-V, --version</span> <span style="color:#888">output the version number</span>
44
- <span style="color:#98c379">-e, --env &lt;env&gt;</span> <span style="color:#888">Target environment</span>
45
- <span style="color:#98c379">-p, --port &lt;n&gt;</span> <span style="color:#888">Port number</span>
46
- <span style="color:#98c379">-r, --retries &lt;n&gt;</span> <span style="color:#888">Retry count</span>
47
- <span style="color:#98c379">--tags &lt;t&gt;</span> <span style="color:#888">Labels</span>
48
- <span style="color:#98c379">-f, --force</span> <span style="color:#888">Skip confirmation</span>
49
- <span style="color:#98c379">-h, --help</span> <span style="color:#888">display help for command</span>
50
- </code></pre>
58
+ <p align="center">
59
+ <img src="help-output.svg" alt="Colorized help output" width="80%" />
60
+ </p>
51
61
 
52
- Help is auto-colorized — bold headings, green flags, cyan commands, dim descriptions. Options with [Zod](https://github.com/colinhacks/zod) schemas or built-in types are validated at parse time with clear error messages.
62
+ Options with [Zod](https://github.com/colinhacks/zod) schemas or built-in types are validated at parse time with clear error messages.
53
63
 
54
64
  ## What's included
55
65
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@silvery/commander",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "Colorized Commander.js help output using ANSI escape codes",
5
5
  "keywords": [
6
6
  "ansi",
@@ -29,16 +29,14 @@
29
29
  "access": "public"
30
30
  },
31
31
  "dependencies": {
32
+ "@silvery/ansi": ">=0.1.0",
33
+ "@silvery/style": ">=0.1.0",
32
34
  "commander": ">=12.0.0"
33
35
  },
34
36
  "peerDependencies": {
35
- "@silvery/ansi": ">=0.1.0",
36
37
  "zod": ">=3.0.0"
37
38
  },
38
39
  "peerDependenciesMeta": {
39
- "@silvery/ansi": {
40
- "optional": true
41
- },
42
40
  "zod": {
43
41
  "optional": true
44
42
  }
package/src/colorize.ts CHANGED
@@ -6,8 +6,6 @@
6
6
  * or plain commander — accepts a minimal CommandLike interface so Commander
7
7
  * is a peer dependency, not a hard one.
8
8
  *
9
- * Zero dependencies — only raw ANSI escape codes.
10
- *
11
9
  * @example
12
10
  * ```ts
13
11
  * import { Command } from "@silvery/commander"
@@ -18,39 +16,27 @@
18
16
  * ```
19
17
  */
20
18
 
21
- // Raw ANSI escape codes no framework dependencies.
19
+ import { MODIFIERS, FG_COLORS } from "@silvery/style"
20
+ import { detectColor } from "@silvery/ansi"
21
+
22
+ // Derive ANSI escape sequences from @silvery/style constants.
22
23
  const RESET = "\x1b[0m"
23
- const BOLD = "\x1b[1m"
24
- const DIM = "\x1b[2m"
25
- const CYAN = "\x1b[36m"
26
- const GREEN = "\x1b[32m"
27
- const YELLOW = "\x1b[33m"
24
+ const BOLD = `\x1b[${MODIFIERS.bold![0]}m`
25
+ const DIM = `\x1b[${MODIFIERS.dim![0]}m`
26
+ const CYAN = `\x1b[${FG_COLORS.cyan}m`
27
+ const GREEN = `\x1b[${FG_COLORS.green}m`
28
+ const YELLOW = `\x1b[${FG_COLORS.yellow}m`
28
29
 
29
30
  /**
30
31
  * Check if color output should be enabled.
31
- * Uses @silvery/ansi detectColor() if available, falls back to basic
32
- * NO_COLOR/FORCE_COLOR/isTTY checks.
32
+ * Uses @silvery/ansi detectColor() for full detection (respects NO_COLOR,
33
+ * FORCE_COLOR, TERM, etc.).
33
34
  */
34
35
  let _shouldColorize: boolean | undefined
35
36
 
36
37
  export function shouldColorize(): boolean {
37
38
  if (_shouldColorize !== undefined) return _shouldColorize
38
-
39
- // Try @silvery/ansi for full detection (respects NO_COLOR, FORCE_COLOR, TERM, etc.)
40
- try {
41
- const { detectColor } = require("@silvery/ansi") as { detectColor: (stdout: NodeJS.WriteStream) => string | null }
42
- _shouldColorize = detectColor(process.stdout) !== null
43
- } catch {
44
- // Fallback: basic NO_COLOR / FORCE_COLOR / isTTY checks
45
- if (process.env.NO_COLOR !== undefined) {
46
- _shouldColorize = false
47
- } else if (process.env.FORCE_COLOR !== undefined) {
48
- _shouldColorize = true
49
- } else {
50
- _shouldColorize = process.stdout?.isTTY ?? true
51
- }
52
- }
53
-
39
+ _shouldColorize = detectColor(process.stdout) !== null
54
40
  return _shouldColorize
55
41
  }
56
42