@wooksjs/event-cli 0.7.8 → 0.7.10

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wooksjs/event-cli",
3
- "version": "0.7.8",
3
+ "version": "0.7.10",
4
4
  "description": "@wooksjs/event-cli",
5
5
  "keywords": [
6
6
  "api",
@@ -25,13 +25,8 @@
25
25
  "url": "git+https://github.com/wooksjs/wooksjs.git",
26
26
  "directory": "packages/event-cli"
27
27
  },
28
- "bin": {
29
- "wooksjs-event-cli-skill": "scripts/setup-skills.js"
30
- },
31
28
  "files": [
32
- "dist",
33
- "skills",
34
- "scripts"
29
+ "dist"
35
30
  ],
36
31
  "main": "dist/index.cjs",
37
32
  "module": "dist/index.mjs",
@@ -52,17 +47,16 @@
52
47
  "@types/minimist": "^1.2.5",
53
48
  "typescript": "^5.9.3",
54
49
  "vitest": "^3.2.4",
55
- "wooks": "^0.7.8",
56
- "@wooksjs/event-core": "^0.7.8"
50
+ "@wooksjs/event-core": "^0.7.10",
51
+ "wooks": "^0.7.10"
57
52
  },
58
53
  "peerDependencies": {
59
54
  "@prostojs/logger": "^0.4.3",
60
55
  "@prostojs/router": "^0.3.3",
61
- "wooks": "^0.7.8",
62
- "@wooksjs/event-core": "^0.7.8"
56
+ "@wooksjs/event-core": "^0.7.10",
57
+ "wooks": "^0.7.10"
63
58
  },
64
59
  "scripts": {
65
- "build": "rolldown -c ../../rolldown.config.mjs",
66
- "setup-skills": "node scripts/setup-skills.js"
60
+ "build": "rolldown -c ../../rolldown.config.mjs"
67
61
  }
68
62
  }
@@ -1,77 +0,0 @@
1
- #!/usr/bin/env node
2
- /* prettier-ignore */
3
- 'use strict'
4
-
5
- const fs = require('fs')
6
- const path = require('path')
7
- const os = require('os')
8
-
9
- const SKILL_NAME = 'wooksjs-event-cli'
10
- const SKILL_SRC = path.join(__dirname, '..', 'skills', SKILL_NAME)
11
-
12
- if (!fs.existsSync(SKILL_SRC)) {
13
- console.error(`No skills found at ${SKILL_SRC}`)
14
- console.error('Add your SKILL.md files to the skills/' + SKILL_NAME + '/ directory first.')
15
- process.exit(1)
16
- }
17
-
18
- const AGENTS = {
19
- 'Claude Code': { dir: '.claude/skills', global: path.join(os.homedir(), '.claude', 'skills') },
20
- 'Cursor': { dir: '.cursor/skills', global: path.join(os.homedir(), '.cursor', 'skills') },
21
- 'Windsurf': { dir: '.windsurf/skills', global: path.join(os.homedir(), '.windsurf', 'skills') },
22
- 'Codex': { dir: '.codex/skills', global: path.join(os.homedir(), '.codex', 'skills') },
23
- 'OpenCode': { dir: '.opencode/skills', global: path.join(os.homedir(), '.opencode', 'skills') },
24
- }
25
-
26
- const args = process.argv.slice(2)
27
- const isGlobal = args.includes('--global') || args.includes('-g')
28
- const isPostinstall = args.includes('--postinstall')
29
- let installed = 0, skipped = 0
30
- const installedDirs = []
31
-
32
- for (const [agentName, cfg] of Object.entries(AGENTS)) {
33
- const targetBase = isGlobal ? cfg.global : path.join(process.cwd(), cfg.dir)
34
- const agentRootDir = path.dirname(cfg.global) // Check if the agent has ever been installed globally
35
-
36
- // In postinstall mode: silently skip agents that aren't set up globally
37
- if (isPostinstall || isGlobal) {
38
- if (!fs.existsSync(agentRootDir)) { skipped++; continue }
39
- }
40
-
41
- const dest = path.join(targetBase, SKILL_NAME)
42
- try {
43
- fs.mkdirSync(dest, { recursive: true })
44
- fs.cpSync(SKILL_SRC, dest, { recursive: true })
45
- console.log(`✅ ${agentName}: installed to ${dest}`)
46
- installed++
47
- if (!isGlobal) installedDirs.push(cfg.dir + '/' + SKILL_NAME)
48
- } catch (err) {
49
- console.warn(`⚠️ ${agentName}: failed — ${err.message}`)
50
- }
51
- }
52
-
53
- // Add locally-installed skill dirs to .gitignore
54
- if (!isGlobal && installedDirs.length > 0) {
55
- const gitignorePath = path.join(process.cwd(), '.gitignore')
56
- let gitignoreContent = ''
57
- try { gitignoreContent = fs.readFileSync(gitignorePath, 'utf8') } catch {}
58
- const linesToAdd = installedDirs.filter(d => !gitignoreContent.includes(d))
59
- if (linesToAdd.length > 0) {
60
- const hasHeader = gitignoreContent.includes('# AI agent skills')
61
- const block = (gitignoreContent && !gitignoreContent.endsWith('\n') ? '\n' : '')
62
- + (hasHeader ? '' : '\n# AI agent skills (auto-generated by setup-skills)\n')
63
- + linesToAdd.join('\n') + '\n'
64
- fs.appendFileSync(gitignorePath, block)
65
- console.log(`📝 Added ${linesToAdd.length} entries to .gitignore`)
66
- }
67
- }
68
-
69
- if (installed === 0 && isPostinstall) {
70
- // Silence is fine — no agents present, nothing to do
71
- } else if (installed === 0 && skipped === Object.keys(AGENTS).length) {
72
- console.log('No agent directories detected. Try --global or run without it for project-local install.')
73
- } else if (installed === 0) {
74
- console.log('Nothing installed. Run without --global to install project-locally.')
75
- } else {
76
- console.log(`\n✨ Done! Restart your AI agent to pick up the "${SKILL_NAME}" skill.`)
77
- }
@@ -1,31 +0,0 @@
1
- ---
2
- name: wooksjs-event-cli
3
- description: Use this skill when working with @wooksjs/event-cli — to build CLI applications with createCliApp(), register commands with app.cli(), parse flags and options with useCliOptions()/useCliOption(), generate auto-help with useCliHelp()/useAutoHelp(), handle unknown commands with useCommandLookupHelp(), define command aliases/args/options metadata, or run CLI commands programmatically with app.run().
4
- ---
5
-
6
- # @wooksjs/event-cli
7
-
8
- CLI adapter for Wooks. Build command-line applications with the same composable architecture as Wooks HTTP — routed commands, typed options, auto-generated help, and per-invocation context.
9
-
10
- ## How to use this skill
11
-
12
- Read the domain file that matches the task. Do not load all files — only what you need.
13
-
14
- | Domain | File | Load when... |
15
- | -------------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
16
- | Core setup & routing | [core.md](core.md) | Creating a CLI app, registering commands, running commands, understanding the architecture |
17
- | Commands & help | [commands.md](commands.md) | Command registration with options/args/aliases, help generation, composables (`useCliOptions`, `useCliHelp`, `useAutoHelp`) |
18
-
19
- ## Quick reference
20
-
21
- ```ts
22
- import { createCliApp } from '@wooksjs/event-cli'
23
- import { useRouteParams, useLogger } from '@wooksjs/event-cli'
24
- import {
25
- useCliOptions,
26
- useCliOption,
27
- useCliHelp,
28
- useAutoHelp,
29
- useCommandLookupHelp,
30
- } from '@wooksjs/event-cli'
31
- ```
@@ -1,222 +0,0 @@
1
- # Commands & help — @wooksjs/event-cli
2
-
3
- > Command registration with options/args/aliases, help generation, and CLI composables.
4
-
5
- ## Concepts
6
-
7
- Commands can be registered with rich metadata (description, options, args, aliases, examples) that drives auto-generated help output. The help system is powered by `@prostojs/cli-help`.
8
-
9
- CLI composables (`useCliOptions`, `useCliOption`, `useCliHelp`, `useAutoHelp`) provide access to parsed flags and help rendering from within handlers.
10
-
11
- ## API Reference
12
-
13
- ### Command registration with options
14
-
15
- ```ts
16
- app.cli('deploy/:env', {
17
- description: 'Deploy the application to the specified environment',
18
- args: {
19
- env: 'Target environment (staging, production)',
20
- },
21
- options: [
22
- { keys: ['verbose', 'v'], description: 'Enable verbose output' },
23
- { keys: ['dry-run', 'd'], description: 'Run without making changes' },
24
- { keys: ['config', 'c'], description: 'Path to config file', value: 'path' },
25
- ],
26
- aliases: ['dep'],
27
- examples: [
28
- {
29
- description: 'Deploy to production with verbose output',
30
- cmd: 'production --verbose',
31
- },
32
- ],
33
- handler: () => {
34
- const { params } = useRouteParams<{ env: string }>()
35
- const verbose = useCliOption('verbose')
36
- return `Deploying to ${params.env}${verbose ? ' (verbose)' : ''}`
37
- },
38
- })
39
- ```
40
-
41
- **`TWooksCliEntry<T>` fields:**
42
-
43
- | Field | Type | Description |
44
- | ------------- | ----------------------------------- | -------------------------------------------------------- |
45
- | `handler` | `TWooksHandler<T>` | The command handler function |
46
- | `description` | `string` | Command description for help |
47
- | `args` | `Record<string, string>` | Argument descriptions (auto-populated from route params) |
48
- | `options` | `TCliOption[]` | Flag/option definitions |
49
- | `aliases` | `string[]` | Alternative command names |
50
- | `examples` | `TCliExample[]` | Usage examples |
51
- | `onRegister` | `(path, aliasType, route?) => void` | Callback when command/alias is registered |
52
-
53
- **Option definition:**
54
-
55
- ```ts
56
- { keys: ['verbose', 'v'], description: 'Enable verbose output' }
57
- { keys: ['config', 'c'], description: 'Config file path', value: 'file' }
58
- ```
59
-
60
- - `keys`: Array of flag names (first is primary, rest are aliases)
61
- - `description`: Help text
62
- - `value`: If present, the option expects a value (shown in help as `--config <file>`)
63
-
64
- ### `useCliOptions(): Record<string, boolean | string>`
65
-
66
- Returns all parsed CLI flags (via `minimist`). Includes positional args in `_`.
67
-
68
- ```ts
69
- import { useCliOptions } from '@wooksjs/event-cli'
70
-
71
- app.cli('build', () => {
72
- const opts = useCliOptions()
73
- // For: $ mycli build --verbose --target=production
74
- // opts = { _: ['build'], verbose: true, target: 'production' }
75
- })
76
- ```
77
-
78
- ### `useCliOption(name: string): boolean | string | undefined`
79
-
80
- Returns a single option value, resolving aliases from the command's option definitions.
81
-
82
- ```ts
83
- import { useCliOption } from '@wooksjs/event-cli'
84
-
85
- app.cli('deploy', {
86
- options: [{ keys: ['verbose', 'v'], description: 'Verbose output' }],
87
- handler: () => {
88
- const verbose = useCliOption('verbose')
89
- // Returns true for both --verbose and -v
90
- },
91
- })
92
- ```
93
-
94
- ### `useCliHelp()`
95
-
96
- Provides access to the help renderer for the current command.
97
-
98
- ```ts
99
- import { useCliHelp } from '@wooksjs/event-cli'
100
-
101
- const { print, render, getEntry, getCliHelp } = useCliHelp()
102
- ```
103
-
104
- | Method | Description |
105
- | ----------------------------- | ------------------------------------------ |
106
- | `print(withColors?)` | Print help to stdout |
107
- | `render(width?, withColors?)` | Render help as string |
108
- | `getEntry()` | Get the help entry for the current command |
109
- | `getCliHelp()` | Get the full `CliHelpRenderer` instance |
110
-
111
- ### `useAutoHelp(keys?, colors?)`
112
-
113
- Checks if `--help` (or custom flag) was passed; if so, prints help and returns `true`.
114
-
115
- ```ts
116
- import { useAutoHelp } from '@wooksjs/event-cli'
117
-
118
- app.cli('build', {
119
- description: 'Build the project',
120
- handler: () => {
121
- if (useAutoHelp()) return // prints help and returns true for --help
122
- return 'Building...'
123
- },
124
- })
125
-
126
- // Custom trigger flags
127
- app.cli('test', {
128
- handler: () => {
129
- if (useAutoHelp(['help', 'h'], false)) return // -h, --help, no colors
130
- },
131
- })
132
- ```
133
-
134
- **Parameters:**
135
-
136
- - `keys` (default: `['help']`) — option names that trigger help
137
- - `colors` (default: `true`) — whether to use ANSI colors
138
-
139
- ### `useCommandLookupHelp(lookupDepth?)`
140
-
141
- Provides "did you mean?" suggestions for unknown commands. Best used in `onUnknownCommand`:
142
-
143
- ```ts
144
- import { createCliApp } from '@wooksjs/event-cli'
145
- import { useCommandLookupHelp } from '@wooksjs/event-cli'
146
-
147
- const app = createCliApp({
148
- onUnknownCommand: (params, raiseError) => {
149
- useCommandLookupHelp() // throws with suggestions if found
150
- raiseError() // fallback: standard "unknown command" error
151
- },
152
- })
153
- ```
154
-
155
- For a command like `run test:drive dir`, it searches backwards:
156
-
157
- 1. `run test:drive dir` (depth 0)
158
- 2. `run test:drive` (depth 1)
159
- 3. `run test` (depth 2)
160
- 4. `run` (depth 3)
161
-
162
- If a match has children, it suggests them. If a match expects args, it says which args are expected.
163
-
164
- ## Common Patterns
165
-
166
- ### Pattern: Auto-help with exit
167
-
168
- ```ts
169
- app.cli('serve', {
170
- description: 'Start the development server',
171
- options: [{ keys: ['port', 'p'], description: 'Port number', value: 'number' }],
172
- handler: () => {
173
- if (useAutoHelp()) process.exit(0)
174
- const port = useCliOption('port') || '3000'
175
- return `Server running on port ${port}`
176
- },
177
- })
178
- ```
179
-
180
- ### Pattern: Boolean and value flags
181
-
182
- ```ts
183
- app.cli('build', {
184
- options: [
185
- { keys: ['watch', 'w'], description: 'Watch mode' }, // boolean
186
- { keys: ['output', 'o'], description: 'Output dir', value: 'path' }, // value
187
- ],
188
- handler: () => {
189
- const watch = useCliOption('watch') // true | undefined
190
- const output = useCliOption('output') // 'dist' | undefined
191
- },
192
- })
193
- ```
194
-
195
- ### Pattern: Shared CLI and HTTP adapters
196
-
197
- Both adapters can share the same `Wooks` instance:
198
-
199
- ```ts
200
- import { createCliApp } from '@wooksjs/event-cli'
201
- import { createHttpApp } from '@wooksjs/event-http'
202
-
203
- const httpApp = createHttpApp()
204
- const cliApp = createCliApp({}, httpApp)
205
-
206
- // CLI commands and HTTP routes share the same router
207
- cliApp.cli('start', () => httpApp.listen(3000))
208
- ```
209
-
210
- ## Best Practices
211
-
212
- - Always provide `description` and `options` for production CLI tools — it powers `--help`
213
- - Use `useAutoHelp()` at the top of every command handler
214
- - Use `useCommandLookupHelp()` in `onUnknownCommand` for better UX
215
- - Use aliases for common abbreviations: `aliases: ['dep']` for `deploy`
216
-
217
- ## Gotchas
218
-
219
- - `useCliOptions()` returns the raw `minimist` output — `_` contains positional args, everything else is flags
220
- - `useCliOption(name)` resolves aliases from the option definitions — `useCliOptions()[name]` does not
221
- - Help is auto-registered from `app.cli()` metadata — no separate help registration needed
222
- - Colons in command names must be escaped: `'use\\:dev'` for command `use:dev`
@@ -1,136 +0,0 @@
1
- # Core setup & routing — @wooksjs/event-cli
2
-
3
- > Creating a CLI app, registering commands, running them, and architecture overview.
4
-
5
- ## Concepts
6
-
7
- `@wooksjs/event-cli` wraps command-line argument parsing with Wooks' composable architecture. Each command invocation gets its own `EventContext`, and handlers are plain functions. Command routing uses the same `@prostojs/router` as the HTTP adapter — supporting parameters, optional params, wildcards, and aliases.
8
-
9
- Arguments are parsed with `minimist`. Help text is generated automatically from command metadata via `@prostojs/cli-help`.
10
-
11
- ## Installation
12
-
13
- ```bash
14
- pnpm add @wooksjs/event-cli
15
- ```
16
-
17
- Peer dependencies: `@wooksjs/event-core`, `wooks`, `@prostojs/router`, `@prostojs/logger`.
18
-
19
- ## API Reference
20
-
21
- ### `createCliApp(opts?): WooksCli`
22
-
23
- Creates a CLI application instance.
24
-
25
- ```ts
26
- import { createCliApp } from '@wooksjs/event-cli'
27
-
28
- const app = createCliApp()
29
-
30
- app.cli('greet/:name', () => {
31
- const { params } = useRouteParams<{ name: string }>()
32
- return `Hello, ${params.name}!`
33
- })
34
-
35
- app.run() // processes process.argv
36
- ```
37
-
38
- **Options (`TWooksCliOptions`):**
39
-
40
- | Option | Type | Description |
41
- | ------------------ | ------------------------------------- | --------------------------------------------------------- |
42
- | `logger` | `TConsoleBase` | Custom logger |
43
- | `onError` | `(e: Error) => void` | Custom error handler (default: print + `process.exit(1)`) |
44
- | `onNotFound` | `TWooksHandler` | Handler for unknown commands |
45
- | `onUnknownCommand` | `(params, raiseError) => unknown` | Callback before "unknown command" error |
46
- | `cliHelp` | `TCliHelpRenderer \| TCliHelpOptions` | Help renderer or options |
47
- | `router` | router options | Custom router configuration |
48
-
49
- ### `app.cli(path, handler | options)`
50
-
51
- Register a CLI command. Path segments can use `/` or space as separators.
52
-
53
- ```ts
54
- // Simple handler
55
- app.cli('build/:target', () => {
56
- const { params } = useRouteParams<{ target: string }>()
57
- return `Building ${params.target}...`
58
- })
59
-
60
- // Equivalent paths:
61
- app.cli('deploy staging', handler)
62
- app.cli('deploy/staging', handler)
63
- ```
64
-
65
- ### `app.run(argv?, minimistOpts?)`
66
-
67
- Start command processing. Defaults to `process.argv.slice(2)`.
68
-
69
- ```ts
70
- // Use process.argv
71
- await app.run()
72
-
73
- // Override argv
74
- await app.run(['build', 'production', '--verbose'])
75
-
76
- // With minimist options
77
- await app.run(['cmd', '-cA'], { boolean: ['A'] })
78
- ```
79
-
80
- Returns the handler's return value, or an `Error` if the command fails.
81
-
82
- ## Command routing
83
-
84
- Routes use the same `@prostojs/router` as HTTP. Command path segments become route segments:
85
-
86
- ```ts
87
- // Static command
88
- app.cli('init', handler) // $ mycli init
89
-
90
- // With parameter
91
- app.cli('build/:target', handler) // $ mycli build production
92
-
93
- // Optional parameter
94
- app.cli('test/:suite?', handler) // $ mycli test (suite = undefined)
95
- // $ mycli test unit (suite = 'unit')
96
-
97
- // Multi-segment
98
- app.cli('deploy staging setup', handler) // $ mycli deploy staging setup
99
- ```
100
-
101
- Route params accessed via `useRouteParams()`:
102
-
103
- ```ts
104
- import { useRouteParams } from '@wooksjs/event-cli'
105
-
106
- app.cli('generate/:type/:name', () => {
107
- const { params } = useRouteParams<{ type: string; name: string }>()
108
- return `Generating ${params.type}: ${params.name}`
109
- })
110
- ```
111
-
112
- ## Response handling
113
-
114
- Handler return values are printed to stdout:
115
-
116
- | Return type | Behavior |
117
- | ----------- | ------------------------------------------------- |
118
- | `string` | `console.log(value)` |
119
- | `array` | Each item logged (strings as-is, objects as JSON) |
120
- | `object` | `console.log(JSON.stringify(value, null, ' '))` |
121
- | `Error` | Passed to `onError` handler |
122
- | `undefined` | Nothing printed |
123
-
124
- ## Best Practices
125
-
126
- - Use `useRouteParams()` for positional arguments and `useCliOptions()` for flags
127
- - Prefer the options object form of `app.cli()` to get auto-generated help
128
- - Use `onUnknownCommand` with `useCommandLookupHelp()` for "did you mean?" suggestions
129
- - Command paths with spaces and `/` are equivalent — use whichever is more readable
130
-
131
- ## Gotchas
132
-
133
- - `app.run()` is async — always `await` it
134
- - Default error handling calls `process.exit(1)` — override with `onError` for testing
135
- - Colons in command names need escaping: `app.cli('use\\:dev', handler)` for `$ mycli use:dev`
136
- - `minimist` treats `--no-flag` as `flag: false` when the flag is in `boolean` array