From cb65c9d2ef196fcdcde2e7b24202c084a7f3d16b Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Sun, 31 May 2026 23:03:40 +0000 Subject: [PATCH 1/2] feat: add inquirerer-cli skill from constructive-skills Move the inquirerer-cli skill (SKILL.md + references/) into .agents/skills/inquirerer-cli/ alongside its source code. Add AGENTS.md listing available skills. --- .agents/skills/inquirerer-cli.zip | Bin 0 -> 15820 bytes .agents/skills/inquirerer-cli/SKILL.md | 55 ++ .../references/inquirerer-anti-patterns.md | 58 ++ .../references/inquirerer-appstash.md | 358 ++++++++++++ .../references/inquirerer-cli-building.md | 539 ++++++++++++++++++ .../references/inquirerer-cli.md | 194 +++++++ .../references/inquirerer-yanse.md | 43 ++ .../references/readme-formatting.md | 264 +++++++++ AGENTS.md | 25 + 9 files changed, 1536 insertions(+) create mode 100644 .agents/skills/inquirerer-cli.zip create mode 100644 .agents/skills/inquirerer-cli/SKILL.md create mode 100644 .agents/skills/inquirerer-cli/references/inquirerer-anti-patterns.md create mode 100644 .agents/skills/inquirerer-cli/references/inquirerer-appstash.md create mode 100644 .agents/skills/inquirerer-cli/references/inquirerer-cli-building.md create mode 100644 .agents/skills/inquirerer-cli/references/inquirerer-cli.md create mode 100644 .agents/skills/inquirerer-cli/references/inquirerer-yanse.md create mode 100644 .agents/skills/inquirerer-cli/references/readme-formatting.md create mode 100644 AGENTS.md diff --git a/.agents/skills/inquirerer-cli.zip b/.agents/skills/inquirerer-cli.zip new file mode 100644 index 0000000000000000000000000000000000000000..11ed867e166be590a1b3a4ceb249aca958fa944d GIT binary patch literal 15820 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 literal 0 HcmV?d00001 diff --git a/.agents/skills/inquirerer-cli/SKILL.md b/.agents/skills/inquirerer-cli/SKILL.md new file mode 100644 index 0000000..93a4b7a --- /dev/null +++ b/.agents/skills/inquirerer-cli/SKILL.md @@ -0,0 +1,55 @@ +--- +name: inquirerer-cli +description: "inquirerer CLI framework — interactive prompts, appStash state persistence, yanse terminal colors, and README formatting conventions. Use when building CLIs with inquirerer or formatting documentation. For pnpm workspace/publishing/monorepo management, see the constructive-pnpm skill instead." +metadata: + author: constructive-io + version: "2.0.0" +--- + +# inquirerer CLI + +Build interactive CLI tools with the inquirerer framework: prompts, appStash state persistence, yanse terminal colors, and documentation formatting. + +## When to Apply + +Use this skill when: +- Building interactive CLIs with `inquirerer` +- Formatting README and documentation files + +**For pnpm workspace management, publishing, and monorepo configuration**, see the `constructive-pnpm` skill. + +## inquirerer CLI Framework + +Build interactive CLI tools with prompts, appStash state persistence, and yanse terminal colors. + +See [inquirerer-cli.md](./references/inquirerer-cli.md) for the CLI framework guide. + +## README Formatting + +Consistent documentation formatting conventions for Constructive projects. + +See [readme-formatting.md](./references/readme-formatting.md) for formatting rules. + +## Reference Guide + +### CLI + +| Reference | Topic | Consult When | +|-----------|-------|--------------| +| [inquirerer-cli.md](./references/inquirerer-cli.md) | inquirerer CLI framework | Building interactive CLI tools | +| [inquirerer-cli-building.md](./references/inquirerer-cli-building.md) | CLI building patterns | Command structure, argument parsing | +| [inquirerer-appstash.md](./references/inquirerer-appstash.md) | appStash state management | Persisting CLI state between runs | +| [inquirerer-yanse.md](./references/inquirerer-yanse.md) | yanse terminal colors | Colored output, styling | +| [inquirerer-anti-patterns.md](./references/inquirerer-anti-patterns.md) | Anti-patterns to avoid | Common mistakes in CLI building | + +### Documentation + +| Reference | Topic | Consult When | +|-----------|-------|--------------| +| [readme-formatting.md](./references/readme-formatting.md) | README conventions | Formatting standards, structure | + +## Cross-References + +- `constructive-pnpm` — PNPM workspace management, publishing, monorepo configuration +- `pgpm` — Uses pnpm workspaces for module management +- `constructive-starter-kits` — Boilerplate templates use these tools diff --git a/.agents/skills/inquirerer-cli/references/inquirerer-anti-patterns.md b/.agents/skills/inquirerer-cli/references/inquirerer-anti-patterns.md new file mode 100644 index 0000000..293d4bc --- /dev/null +++ b/.agents/skills/inquirerer-cli/references/inquirerer-anti-patterns.md @@ -0,0 +1,58 @@ +--- +name: inquirerer-anti-patterns +description: Anti-patterns for CLI development. Do NOT use commander, inquirer.js, yargs, or other CLI libraries in Constructive projects. Use inquirerer instead. Triggers on "commander", "inquirer.js", "yargs", "CLI library", or when reviewing CLI code. +compatibility: inquirerer, Node.js 18+, TypeScript +metadata: + author: constructive-io + version: "1.0.0" + type: anti-pattern +--- + +# CLI Anti-Patterns: Avoid These Libraries + +This skill defines what NOT to do when building CLI tools in Constructive projects. All CLI development should use `inquirerer` instead of other CLI libraries. + +## When to Apply + +Apply this skill when: +- Reviewing code that imports commander, inquirer.js, yargs, or similar +- Someone asks about using a CLI library other than inquirerer +- Creating a new CLI tool and considering which library to use + +## Forbidden Libraries + +Do NOT use these libraries in Constructive projects: + +| Library | Reason to Avoid | +|---------|-----------------| +| `commander` | Separate argument parsing, no integrated prompts | +| `inquirer` / `inquirer.js` | Outdated, not TypeScript-first, different API | +| `yargs` | Complex API, no integrated prompts | +| `prompts` | Limited features, no resolver system | +| `enquirer` | Different API, no Constructive integration | +| `vorpal` | Unmaintained, complex | +| `oclif` | Heavyweight framework, overkill for most uses | +| `meow` | Minimal, no prompt support | +| `arg` | Argument parsing only | +| `minimist` (directly) | Use inquirerer's `parseArgv` wrapper instead | +| `ora` | Use inquirerer's `createSpinner` instead | +| `cli-progress` | Use inquirerer's `createProgress` instead | + +## Why inquirerer is the Standard + +inquirerer is the standard CLI library for all Constructive monorepos because it provides a unified approach across all our projects: + +1. **Consistency**: All Constructive CLIs have the same look, feel, and behavior +2. **TypeScript-first**: Full type safety for questions and answers +3. **Integrated**: Single library for argument parsing, prompts, and UI components +4. **Dynamic defaults**: Built-in resolvers for git config, npm, dates, workspace info +5. **CI/CD ready**: Non-interactive mode works without code changes +6. **Maintained**: Actively developed as part of Constructive tooling + +By standardizing on inquirerer, developers can move between Constructive projects and immediately understand how CLI tools work without learning different libraries. + +## References + +- Use instead: `inquirerer` - https://www.npmjs.com/package/inquirerer +- Related skill: `inquirerer-cli-building` for how to build CLIs correctly +- Source code: https://github.com/constructive-io/dev-utils/tree/main/packages/inquirerer diff --git a/.agents/skills/inquirerer-cli/references/inquirerer-appstash.md b/.agents/skills/inquirerer-cli/references/inquirerer-appstash.md new file mode 100644 index 0000000..a82f9d9 --- /dev/null +++ b/.agents/skills/inquirerer-cli/references/inquirerer-appstash.md @@ -0,0 +1,358 @@ +--- +name: appstash-cli +description: Use appstash for CLI application directory management. Apply when building CLI tools that need config storage, caching, logging, or update checking. +compatibility: Node.js 18+, TypeScript +metadata: + author: constructive-io + version: "1.0.0" +--- + +# appstash CLI Directory Management + +Use `appstash` for simple, clean application directory resolution in CLI tools. It provides consistent paths for config, cache, data, logs, and temp directories with graceful fallback handling. + +## When to Apply + +Use this skill when: +- Building a CLI tool that needs to store configuration +- Implementing persistent caching for CLI operations +- Managing API keys or auth tokens for CLI tools +- Adding logging to CLI applications +- Storing temporary files during CLI operations + +## Installation + +```bash +npm install appstash +# or +pnpm add appstash +``` + +## Core Concepts + +### Directory Structure + +appstash creates a clean directory structure under the user's home directory: + +``` +~/./ + ├── config/ # Configuration files (settings, auth profiles) + ├── cache/ # Cached data (repos, API responses) + ├── data/ # Application data (databases, state) + └── logs/ # Log files + +/tmp// # Temporary files (ephemeral) +``` + +### Fallback Chain + +appstash never throws errors. If the home directory is unavailable: +1. Falls back to XDG directories (`~/.config/`, `~/.cache/`, etc.) +2. Falls back to system temp (`/tmp//`) + +## Basic Usage + +```typescript +import { appstash, resolve } from 'appstash'; + +// Get directories for your CLI tool +const dirs = appstash('mycli', { ensure: true }); + +console.log(dirs.config); // ~/.mycli/config +console.log(dirs.cache); // ~/.mycli/cache +console.log(dirs.data); // ~/.mycli/data +console.log(dirs.logs); // ~/.mycli/logs +console.log(dirs.tmp); // /tmp/mycli +``` + +## Common Patterns + +### Storing Auth Profiles + +Store multiple API endpoints and tokens for CLI tools: + +```typescript +import { appstash, resolve } from 'appstash'; +import * as fs from 'fs'; + +interface AuthProfile { + endpoint: string; + token?: string; +} + +interface CliConfig { + current?: string; + profiles: Record; +} + +const dirs = appstash('mycli', { ensure: true }); +const configFile = resolve(dirs, 'config', 'auth.json'); + +function loadConfig(): CliConfig { + if (fs.existsSync(configFile)) { + return JSON.parse(fs.readFileSync(configFile, 'utf8')); + } + return { profiles: {} }; +} + +function saveConfig(config: CliConfig): void { + fs.writeFileSync(configFile, JSON.stringify(config, null, 2)); +} + +function addProfile(name: string, endpoint: string, token?: string): void { + const config = loadConfig(); + config.profiles[name] = { endpoint, token }; + if (!config.current) { + config.current = name; + } + saveConfig(config); +} + +function useProfile(name: string): void { + const config = loadConfig(); + if (!config.profiles[name]) { + throw new Error(`Profile "${name}" not found`); + } + config.current = name; + saveConfig(config); +} + +function getActiveProfile(): AuthProfile | null { + const config = loadConfig(); + if (config.current && config.profiles[config.current]) { + return config.profiles[config.current]; + } + return null; +} +``` + +### Caching API Responses + +```typescript +import { appstash, resolve } from 'appstash'; +import * as fs from 'fs'; +import * as path from 'path'; + +const dirs = appstash('mycli', { ensure: true }); + +interface CacheEntry { + data: T; + timestamp: number; +} + +function getCached(key: string, ttlMs: number): T | null { + const cachePath = resolve(dirs, 'cache', `${key}.json`); + + if (!fs.existsSync(cachePath)) { + return null; + } + + const entry: CacheEntry = JSON.parse(fs.readFileSync(cachePath, 'utf8')); + const age = Date.now() - entry.timestamp; + + if (age > ttlMs) { + fs.unlinkSync(cachePath); + return null; + } + + return entry.data; +} + +function setCache(key: string, data: T): void { + const cachePath = resolve(dirs, 'cache', `${key}.json`); + fs.mkdirSync(path.dirname(cachePath), { recursive: true }); + + const entry: CacheEntry = { + data, + timestamp: Date.now(), + }; + + fs.writeFileSync(cachePath, JSON.stringify(entry)); +} +``` + +### Logging + +```typescript +import { appstash, resolve } from 'appstash'; +import * as fs from 'fs'; + +const dirs = appstash('mycli', { ensure: true }); +const logFile = resolve(dirs, 'logs', 'cli.log'); + +function log(level: 'info' | 'warn' | 'error', message: string): void { + const timestamp = new Date().toISOString(); + const line = `[${timestamp}] [${level.toUpperCase()}] ${message}\n`; + fs.appendFileSync(logFile, line); +} +``` + +### Update Checking with @inquirerer/utils + +Combine appstash with `@inquirerer/utils` for update checking: + +```typescript +import { appstash, resolve } from 'appstash'; +import { checkForUpdates } from '@inquirerer/utils'; +import * as fs from 'fs'; + +const dirs = appstash('mycli', { ensure: true }); +const updateCacheFile = resolve(dirs, 'cache', 'update-check.json'); + +async function checkUpdates(pkgName: string, pkgVersion: string): Promise { + // Check if we've checked recently (within 24 hours) + if (fs.existsSync(updateCacheFile)) { + const cache = JSON.parse(fs.readFileSync(updateCacheFile, 'utf8')); + const age = Date.now() - cache.timestamp; + if (age < 24 * 60 * 60 * 1000) { + return; // Skip check + } + } + + const result = await checkForUpdates({ + pkgName, + pkgVersion, + toolName: 'mycli', + }); + + // Cache the check timestamp + fs.writeFileSync(updateCacheFile, JSON.stringify({ timestamp: Date.now() })); + + if (result.hasUpdate && result.message) { + console.warn(result.message); + console.warn('Run `npm update -g mycli` to upgrade.'); + } +} +``` + +## Integration with inquirerer CLI + +When building CLIs with `inquirerer`, use appstash for all persistent storage: + +```typescript +import { CLI, CLIOptions, Inquirerer, ParsedArgs } from 'inquirerer'; +import { appstash, resolve } from 'appstash'; + +const dirs = appstash('mycli', { ensure: true }); + +// Auth command using appstash +const authCommand = async (argv: Partial, prompter: Inquirerer) => { + const configFile = resolve(dirs, 'config', 'auth.json'); + + // ... implement auth management +}; + +// Main CLI setup +const commands = async (argv: Partial, prompter: Inquirerer, options: CLIOptions) => { + // ... command routing +}; + +const app = new CLI(commands, { + minimistOpts: { + alias: { v: 'version', h: 'help' } + } +}); + +app.run(); +``` + +## Environment Variable Override + +Always allow environment variables to override stored config: + +```typescript +import { appstash, resolve } from 'appstash'; + +function getEndpoint(): string { + // Environment variable takes precedence + if (process.env.MYCLI_ENDPOINT) { + return process.env.MYCLI_ENDPOINT; + } + + // Fall back to stored profile + const profile = getActiveProfile(); + return profile?.endpoint || 'http://localhost:3000'; +} + +function getAuthToken(): string | undefined { + // Environment variable takes precedence + if (process.env.MYCLI_TOKEN) { + return process.env.MYCLI_TOKEN; + } + + // Fall back to stored profile + const profile = getActiveProfile(); + return profile?.token; +} +``` + +## Testing + +Isolate tests using custom `baseDir`: + +```typescript +import { appstash } from 'appstash'; +import * as fs from 'fs'; +import * as os from 'os'; +import * as path from 'path'; + +describe('CLI config', () => { + let testDirs: ReturnType; + + beforeEach(() => { + testDirs = appstash('mycli', { + baseDir: fs.mkdtempSync(path.join(os.tmpdir(), 'test-')), + ensure: true + }); + }); + + afterEach(() => { + fs.rmSync(testDirs.root, { recursive: true, force: true }); + }); + + it('should store config', () => { + // Test with isolated directories + }); +}); +``` + +## API Reference + +### `appstash(tool, options?)` + +Get application directories for a tool. + +**Parameters:** +- `tool` (string): Tool name (e.g., 'pgpm', 'mycli') +- `options.baseDir` (string): Custom base directory (default: `os.homedir()`) +- `options.ensure` (boolean): Create directories if missing (default: `false`) +- `options.useXdgFallback` (boolean): Use XDG fallback if home fails (default: `true`) +- `options.tmpRoot` (string): Root for temp directory (default: `os.tmpdir()`) + +**Returns:** `AppStashResult` with `root`, `config`, `cache`, `data`, `logs`, `tmp` paths + +### `resolve(dirs, kind, ...parts)` + +Resolve a path within a specific directory. + +**Parameters:** +- `dirs`: Result from `appstash()` +- `kind`: 'config' | 'cache' | 'data' | 'logs' | 'tmp' +- `parts`: Path segments to join + +**Returns:** Resolved path string + +### `ensure(dirs)` + +Create directories if they don't exist. + +**Parameters:** +- `dirs`: Result from `appstash()` + +**Returns:** `{ created: string[], usedFallback: boolean }` + +## References + +- Package: https://www.npmjs.com/package/appstash +- Source: https://github.com/constructive-io/dev-utils/tree/main/packages/appstash +- Related: `inquirerer` for CLI building, `@inquirerer/utils` for update checking diff --git a/.agents/skills/inquirerer-cli/references/inquirerer-cli-building.md b/.agents/skills/inquirerer-cli/references/inquirerer-cli-building.md new file mode 100644 index 0000000..2384553 --- /dev/null +++ b/.agents/skills/inquirerer-cli/references/inquirerer-cli-building.md @@ -0,0 +1,539 @@ +--- +name: inquirerer-cli-building +description: Build interactive CLI tools with inquirerer. Use when asked to "create a CLI", "build a command-line tool", "add prompts", "create interactive prompts", or when building any CLI application in a Constructive project. +compatibility: inquirerer, Node.js 18+, TypeScript +metadata: + author: constructive-io + version: "1.0.0" +--- + +# Building CLI Tools with inquirerer + +A comprehensive guide to building interactive command-line interfaces using inquirerer, the TypeScript-first CLI library used across Constructive projects. + +## When to Apply + +Use this skill when: +- Creating a new CLI application +- Adding interactive prompts to an existing tool +- Building project scaffolding or setup wizards +- Creating configuration builders +- Implementing any command-line interface in a Constructive project + +## Installation + +```bash +pnpm add inquirerer +``` + +## Quick Start + +```typescript +import { Inquirerer } from 'inquirerer'; + +const prompter = new Inquirerer(); + +const answers = await prompter.prompt({}, [ + { + type: 'text', + name: 'projectName', + message: 'What is your project name?', + required: true + }, + { + type: 'confirm', + name: 'useTypeScript', + message: 'Use TypeScript?', + default: true + } +]); + +console.log(answers); +prompter.close(); +``` + +## Question Types + +inquirerer supports six question types: + +### Text Question + +Collect string input: + +```typescript +{ + type: 'text', + name: 'username', + message: 'Enter your username', + required: true, + pattern: '^[a-z0-9_]+$', // Regex validation + default: 'user' +} +``` + +### Number Question + +Collect numeric input: + +```typescript +{ + type: 'number', + name: 'port', + message: 'Server port?', + default: 3000, + validate: (port) => port > 0 && port < 65536 +} +``` + +### Confirm Question + +Yes/no questions: + +```typescript +{ + type: 'confirm', + name: 'proceed', + message: 'Continue with installation?', + default: true +} +``` + +### List Question + +Select one option (no search): + +```typescript +{ + type: 'list', + name: 'license', + message: 'Choose a license', + options: ['MIT', 'Apache-2.0', 'GPL-3.0'], + default: 'MIT', + maxDisplayLines: 5 +} +``` + +### Autocomplete Question + +Select with fuzzy search: + +```typescript +{ + type: 'autocomplete', + name: 'framework', + message: 'Choose a framework', + options: [ + { name: 'React', value: 'react' }, + { name: 'Vue.js', value: 'vue' }, + { name: 'Angular', value: 'angular' } + ], + allowCustomOptions: true, + maxDisplayLines: 8 +} +``` + +### Checkbox Question + +Multi-select with search: + +```typescript +{ + type: 'checkbox', + name: 'features', + message: 'Select features', + options: ['Auth', 'Database', 'API', 'Testing'], + default: ['Auth', 'API'], + returnFullResults: false, // Only return selected items + required: true +} +``` + +## Question Properties + +All questions support these base properties: + +| Property | Type | Description | +|----------|------|-------------| +| `name` | string | Property name in result object | +| `type` | string | Question type | +| `message` | string | Prompt message to display | +| `default` | any | Default value | +| `required` | boolean | Whether input is required | +| `validate` | function | Custom validation function | +| `sanitize` | function | Transform input before storing | +| `pattern` | string | Regex pattern for validation | +| `when` | function | Conditional display | +| `dependsOn` | string[] | Question dependencies | +| `_` | boolean | Mark as positional argument | +| `alias` | string/string[] | Short flag aliases | +| `defaultFrom` | string | Dynamic default from resolver | +| `setFrom` | string | Auto-set value from resolver | + +## Validation + +### Pattern Validation + +```typescript +{ + type: 'text', + name: 'email', + message: 'Enter email', + pattern: '^[^@]+@[^@]+\\.[^@]+$' +} +``` + +### Custom Validation + +```typescript +{ + type: 'text', + name: 'password', + message: 'Enter password', + validate: (input) => { + if (input.length < 8) { + return { success: false, reason: 'Must be at least 8 characters' }; + } + return { success: true }; + } +} +``` + +### Sanitization + +```typescript +{ + type: 'text', + name: 'tags', + message: 'Enter tags (comma-separated)', + sanitize: (input) => input.split(',').map(t => t.trim()) +} +``` + +## Conditional Questions + +Show questions based on previous answers: + +```typescript +const questions = [ + { + type: 'confirm', + name: 'useDatabase', + message: 'Need a database?', + default: false + }, + { + type: 'list', + name: 'database', + message: 'Which database?', + options: ['PostgreSQL', 'MySQL', 'SQLite'], + when: (answers) => answers.useDatabase === true + } +]; +``` + +## Question Dependencies + +Ensure questions appear in correct order: + +```typescript +[ + { + type: 'checkbox', + name: 'services', + message: 'Select services', + options: ['Auth', 'Storage', 'Functions'] + }, + { + type: 'text', + name: 'authProvider', + message: 'Auth provider?', + dependsOn: ['services'], + when: (answers) => answers.services?.includes('Auth') + } +] +``` + +## Positional Arguments + +Allow values without flags using `_: true`: + +```typescript +const questions = [ + { _: true, name: 'source', type: 'text', message: 'Source file' }, + { _: true, name: 'dest', type: 'text', message: 'Destination' } +]; + +// Users can run: mycli input.txt output.txt +// Instead of: mycli --source input.txt --dest output.txt +``` + +## Aliases + +Define short flags: + +```typescript +{ + name: 'workspace', + type: 'confirm', + alias: 'w', // or ['w', 'ws'] for multiple + message: 'Create workspace?' +} + +// Users can run: mycli -w +// Instead of: mycli --workspace +``` + +## Dynamic Defaults with Resolvers + +Auto-populate defaults from git, npm, or custom sources: + +```typescript +const questions = [ + { + type: 'text', + name: 'author', + message: 'Author name?', + defaultFrom: 'git.user.name' // Auto-fills from git config + }, + { + type: 'text', + name: 'email', + message: 'Email?', + defaultFrom: 'git.user.email' + }, + { + type: 'text', + name: 'year', + message: 'Copyright year?', + defaultFrom: 'date.year' + } +]; +``` + +### Built-in Resolvers + +| Resolver | Description | +|----------|-------------| +| `git.user.name` | Git global user name | +| `git.user.email` | Git global user email | +| `npm.whoami` | Logged in npm user | +| `date.year` | Current year | +| `date.month` | Current month | +| `date.day` | Current day | +| `date.iso` | ISO date (YYYY-MM-DD) | +| `workspace.name` | Package name from nearest package.json | +| `workspace.license` | License from package.json | +| `workspace.author` | Author from package.json | + +### Custom Resolvers + +```typescript +import { registerDefaultResolver } from 'inquirerer'; + +registerDefaultResolver('cwd.name', () => { + return process.cwd().split('/').pop(); +}); + +// Use in questions +{ + type: 'text', + name: 'projectName', + defaultFrom: 'cwd.name' +} +``` + +### setFrom vs defaultFrom + +- `defaultFrom`: Sets as default, user can override +- `setFrom`: Auto-sets value, skips prompt entirely + +```typescript +{ + type: 'text', + name: 'createdAt', + setFrom: 'date.iso' // Auto-set, no prompt shown +} +``` + +## CLI Class + +For complete CLI applications with argument parsing: + +```typescript +import { CLI, CommandHandler, CLIOptions } from 'inquirerer'; + +const handler: CommandHandler = async (argv, prompter, options) => { + const answers = await prompter.prompt(argv, [ + { type: 'text', name: 'name', message: 'Name?', required: true } + ]); + console.log('Hello,', answers.name); +}; + +const options: Partial = { + version: 'myapp@1.0.0', + minimistOpts: { + alias: { v: 'version', h: 'help' } + } +}; + +const cli = new CLI(handler, options); +await cli.run(); +``` + +## CLI Utilities + +inquirerer provides utilities for building CLIs: + +```typescript +import { + parseArgv, // Parse command-line arguments + extractFirst, // Extract subcommand + getPackageVersion, // Get version from package.json + cliExitWithError // Exit with error message +} from 'inquirerer'; + +const argv = parseArgv(process.argv); +const { first: command, newArgv } = extractFirst(argv); + +switch (command) { + case 'init': + await handleInit(newArgv); + break; + case 'build': + await handleBuild(newArgv); + break; + default: + console.log('Unknown command'); +} +``` + +## UI Components + +### Spinner + +```typescript +import { createSpinner } from 'inquirerer'; + +const spinner = createSpinner('Loading...'); +spinner.start(); +await doWork(); +spinner.succeed('Done!'); +// Or: spinner.fail('Failed'), spinner.warn('Warning') +``` + +### Progress Bar + +```typescript +import { createProgress } from 'inquirerer'; + +const progress = createProgress('Installing'); +progress.start(); +for (let i = 0; i < items.length; i++) { + await processItem(items[i]); + progress.update((i + 1) / items.length); +} +progress.complete('Installed'); +``` + +### Streaming Text + +```typescript +import { createStream } from 'inquirerer'; + +const stream = createStream({ showCursor: true }); +stream.start(); +for await (const token of llmResponse) { + stream.append(token); +} +stream.done(); +``` + +## Non-Interactive Mode + +For CI/CD environments: + +```typescript +const prompter = new Inquirerer({ + noTty: true, // Disable interactive mode + useDefaults: true // Use defaults without prompting +}); +``` + +## Complete Example + +```typescript +import { Inquirerer, Question, parseArgv } from 'inquirerer'; + +interface ProjectConfig { + name: string; + description: string; + typescript: boolean; + features: string[]; +} + +const argv = parseArgv(process.argv); +const prompter = new Inquirerer(); + +const questions: Question[] = [ + { + _: true, + type: 'text', + name: 'name', + message: 'Project name', + required: true, + pattern: '^[a-z0-9-]+$', + defaultFrom: 'cwd.name' + }, + { + type: 'text', + name: 'description', + message: 'Description', + default: 'My awesome project' + }, + { + type: 'confirm', + name: 'typescript', + alias: 'ts', + message: 'Use TypeScript?', + default: true + }, + { + type: 'checkbox', + name: 'features', + message: 'Select features', + options: ['ESLint', 'Prettier', 'Jest', 'Husky'], + default: ['ESLint', 'Prettier'] + } +]; + +const config = await prompter.prompt(argv, questions); +console.log('Creating project:', config); +prompter.close(); +``` + +Run interactively or with CLI args: + +```bash +# Interactive +node setup.js + +# With args +node setup.js my-project --ts --features ESLint,Jest +``` + +## Best Practices + +1. **Always close the prompter** when done: `prompter.close()` +2. **Use TypeScript interfaces** for type-safe answers +3. **Provide defaults** for better UX +4. **Use `defaultFrom`** for dynamic defaults from git/npm +5. **Support non-interactive mode** for CI/CD +6. **Use positional arguments** for common inputs +7. **Add aliases** for frequently used flags +8. **Validate early** with patterns and custom validators + +## References + +- npm package: https://www.npmjs.com/package/inquirerer +- Related skill: `inquirerer-anti-patterns` for what NOT to do +- Related skill: `pnpm-workspace` for monorepo setup diff --git a/.agents/skills/inquirerer-cli/references/inquirerer-cli.md b/.agents/skills/inquirerer-cli/references/inquirerer-cli.md new file mode 100644 index 0000000..8789053 --- /dev/null +++ b/.agents/skills/inquirerer-cli/references/inquirerer-cli.md @@ -0,0 +1,194 @@ +--- +name: inquirerer-cli +description: Build interactive CLI tools with inquirerer, appstash, and yanse. Use when asked to "create a CLI", "build a command-line tool", "add prompts", "create interactive prompts", "store CLI config", "add terminal colors", or when building any CLI application in a Constructive project. Also triggers on "commander", "inquirer.js", "yargs" to redirect to inquirerer. +compatibility: inquirerer, appstash, yanse, Node.js 18+, TypeScript +metadata: + author: constructive-io + version: "2.0.0" +--- + +# inquirerer CLI Development + +Build interactive command-line interfaces using Constructive's CLI toolkit: **inquirerer** for prompts and argument parsing, **appstash** for persistent storage, and **yanse** for terminal colors. + +## When to Apply + +Use this skill when: +- **Building CLIs:** Creating interactive prompts, argument parsing, subcommands +- **Storing config:** Auth profiles, caching, logging, temp files +- **Terminal output:** Colors, spinners, progress bars, streaming text +- **Reviewing CLI code:** Redirecting from forbidden libraries to inquirerer + +## Quick Start + +```bash +pnpm add inquirerer appstash yanse +``` + +```typescript +import { Inquirerer } from 'inquirerer'; + +const prompter = new Inquirerer(); + +const answers = await prompter.prompt({}, [ + { + type: 'text', + name: 'projectName', + message: 'What is your project name?', + required: true + }, + { + type: 'confirm', + name: 'useTypeScript', + message: 'Use TypeScript?', + default: true + } +]); + +console.log(answers); +prompter.close(); +``` + +## Critical: Forbidden Libraries + +Do NOT use these libraries in Constructive projects: + +| Library | Use Instead | +|---------|-------------| +| `commander` | `inquirerer` CLI class | +| `inquirer` / `inquirer.js` | `inquirerer` | +| `yargs` | `inquirerer` parseArgv | +| `prompts` / `enquirer` | `inquirerer` | +| `chalk` | `yanse` | +| `ora` | `inquirerer` createSpinner | +| `cli-progress` | `inquirerer` createProgress | +| `minimist` (directly) | `inquirerer` parseArgv | + +## Question Types + +| Type | Description | +|------|-------------| +| `text` | String input with pattern validation | +| `number` | Numeric input with custom validation | +| `confirm` | Yes/no boolean | +| `list` | Select one option (no search) | +| `autocomplete` | Select with fuzzy search | +| `checkbox` | Multi-select with search | + +## CLI Application Pattern + +```typescript +import { CLI, CommandHandler, CLIOptions } from 'inquirerer'; + +const handler: CommandHandler = async (argv, prompter, options) => { + const answers = await prompter.prompt(argv, [ + { type: 'text', name: 'name', message: 'Name?', required: true } + ]); + console.log('Hello,', answers.name); +}; + +const cli = new CLI(handler, { + version: 'myapp@1.0.0', + minimistOpts: { alias: { v: 'version', h: 'help' } } +}); + +await cli.run(); +``` + +## Terminal Colors with yanse + +```typescript +// Use yanse instead of chalk (same API, works with CJS + ESM) +import chalk from 'yanse'; + +console.log(chalk.green('Success!')); +console.log(chalk.red.bold('Error!')); +``` + +## Persistent Storage with appstash + +```typescript +import { appstash, resolve } from 'appstash'; + +const dirs = appstash('mycli', { ensure: true }); +// dirs.config → ~/.mycli/config +// dirs.cache → ~/.mycli/cache +// dirs.data → ~/.mycli/data +// dirs.logs → ~/.mycli/logs +// dirs.tmp → /tmp/mycli + +const configFile = resolve(dirs, 'config', 'auth.json'); +``` + +## UI Components + +```typescript +import { createSpinner, createProgress, createStream } from 'inquirerer'; + +// Spinner +const spinner = createSpinner('Loading...'); +spinner.start(); +await doWork(); +spinner.succeed('Done!'); + +// Progress bar +const progress = createProgress('Installing'); +progress.start(); +progress.update(0.5); +progress.complete('Installed'); + +// Streaming text (for LLM output) +const stream = createStream({ showCursor: true }); +stream.start(); +stream.append(token); +stream.done(); +``` + +## Dynamic Defaults + +```typescript +{ + type: 'text', + name: 'author', + message: 'Author?', + defaultFrom: 'git.user.name' // Auto-fills from git config +} +``` + +Built-in resolvers: `git.user.name`, `git.user.email`, `npm.whoami`, `date.year`, `date.iso`, `workspace.name`, `workspace.license`, `workspace.author`. + +## Non-Interactive Mode (CI/CD) + +```typescript +const prompter = new Inquirerer({ + noTty: true, + useDefaults: true +}); +``` + +## Best Practices + +1. **Always close the prompter** when done: `prompter.close()` +2. **Use TypeScript interfaces** for type-safe answers +3. **Support non-interactive mode** for CI/CD +4. **Use `defaultFrom`** for dynamic defaults from git/npm +5. **Use appstash** for all persistent CLI storage +6. **Use yanse** instead of chalk for terminal colors +7. **Environment variables override** stored config + +## Reference Guide + +Consult these reference files for detailed documentation on specific topics: + +| Reference | Topic | Consult When | +|-----------|-------|--------------| +| [references/cli-building.md](references/cli-building.md) | Building CLIs with inquirerer | Question types, validation, conditional questions, positional args, aliases, resolvers, CLI class | +| [references/anti-patterns.md](references/anti-patterns.md) | Forbidden CLI libraries | Reviewing code that uses commander/inquirer.js/yargs, choosing a CLI library | +| [references/appstash.md](references/appstash.md) | CLI directory management | Auth profiles, caching, logging, update checking, environment overrides, testing | +| [references/yanse.md](references/yanse.md) | Terminal color styling | Replacing chalk imports, color API reference | + +## Cross-References + +Related skills (separate from this skill): +- `constructive-pnpm` — Monorepo setup for CLI packages +- `pgpm` — pgpm CLI is built with inquirerer diff --git a/.agents/skills/inquirerer-cli/references/inquirerer-yanse.md b/.agents/skills/inquirerer-cli/references/inquirerer-yanse.md new file mode 100644 index 0000000..1f78460 --- /dev/null +++ b/.agents/skills/inquirerer-cli/references/inquirerer-yanse.md @@ -0,0 +1,43 @@ +--- +name: yanse-terminal-colors +description: Use yanse for terminal color styling instead of chalk. Use when adding colors to CLI output or terminal logs in Constructive projects. +--- + +Use `yanse` for terminal color styling instead of `chalk`. + +## When to Apply + +Use this skill when adding colors to CLI output or terminal logs. + +## Overview + +`yanse` is a chalk-compatible terminal color library with zero dependencies. It exists because chalk v5+ is ESM-only, which causes issues in CommonJS projects. + +The API is identical to chalk - if you know chalk, you know yanse. + +## Anti-Pattern + +```typescript +// Do not use chalk +import chalk from 'chalk'; +``` + +## Pattern + +```typescript +// Use yanse instead +import chalk from 'yanse'; +``` + +That's it. Same API, just a different import. + +## Why yanse? + +- Zero dependencies (chalk has dependencies) +- Supports both ESM and CommonJS (chalk v5+ is ESM-only) +- Identical API to chalk - no learning curve + +## References + +- [yanse on npm](https://www.npmjs.com/package/yanse) +- [chalk documentation](https://github.com/chalk/chalk) (API is the same) diff --git a/.agents/skills/inquirerer-cli/references/readme-formatting.md b/.agents/skills/inquirerer-cli/references/readme-formatting.md new file mode 100644 index 0000000..89e5186 --- /dev/null +++ b/.agents/skills/inquirerer-cli/references/readme-formatting.md @@ -0,0 +1,264 @@ +--- +name: readme-formatting +description: Format README files with Constructive branding including header logos and badges. Use when creating new packages, publishing modules, or when asked to "add header image", "add badges", "format README", or "standardize README". +compatibility: npm, pnpm, pgpm, any package type +metadata: + author: constructive-io + version: "1.0.0" +--- + +# README Formatting (Constructive Standard) + +Format README files with consistent Constructive branding including centered header logos and appropriate badges for different package types. + +## When to Apply + +Use this skill when: +- Creating a new npm, pnpm, or pgpm package +- Publishing a module to npm or pgpm registry +- Asked to add header images or badges to a README +- Standardizing README formatting across packages +- A README is missing the Constructive logo header + +## Header Logo + +All Constructive packages should include a centered logo at the top of the README, immediately after the package title. + +### Standard Header (Most Packages) + +```markdown +# package-name + +

+ +

+``` + +### Root Repository Header + +For root-level README files (monorepo roots), use the filled logo with smaller height: + +```markdown +# Repository Name + +

+ +

+``` + +## Badges + +Badges appear in a centered paragraph below the logo. Include badges based on package type and visibility. + +### Badge Types + +| Badge | When to Use | Example | +|-------|-------------|---------| +| CI Status | Public repos with GitHub Actions | Shows build status | +| License | All public packages | MIT, Apache-2.0, etc. | +| npm Version | npm/pnpm packages published to registry | Shows current version | +| Downloads | Optional, for popular packages | Shows download count | + +### Badge Templates + +**CI Status Badge:** +```html +
+ + +``` + +**MIT License Badge:** +```html + + + +``` + +**npm Version Badge (from package.json in repo):** +```html + + + +``` + +**npm Version Badge (from npm registry):** +```html + + + +``` + +**Downloads Badge (optional):** +```html + + + +``` + +### Complete Badge Section + +```markdown +

+ + + + + + + + + +

+``` + +## Package Type Guidelines + +### npm/pnpm Packages (Published to npm) + +Include: Logo + CI badge + License badge + Version badge + +```markdown +# @scope/package-name + +

+ +

+ +

+ + + + + + + + + +

+ +Package description here. +``` + +### pgpm Packages (PostgreSQL Modules) + +Include: Logo + CI badge + License badge (no npm version badge) + +```markdown +# @pgpm/module-name + +

+ +

+ +

+ + + + + + +

+ +Module description here. +``` + +### Internal/Private Packages + +Include: Logo only (no badges needed) + +```markdown +# package-name + +

+ +

+ +Package description here. +``` + +### Packages with Custom License + +For packages with "All Rights Reserved" or custom licenses, omit the license badge: + +```markdown +

+ + + +

+``` + +## Complete README Template + +```markdown +# @scope/package-name + +

+ +

+ +

+ + + + + + + + + +

+ +Brief description of what the package does. + +## Installation + +\`\`\`bash +pnpm add @scope/package-name +\`\`\` + +## Usage + +\`\`\`typescript +import { something } from '@scope/package-name'; +\`\`\` + +## API + +Document the main exports and functions. + +## License + +MIT (or appropriate license) +``` + +## Checklist + +When formatting a README, verify: + +- [ ] Package title is at the top (h1) +- [ ] Logo is centered below the title +- [ ] Logo uses correct URL (outline-logo.svg for packages, logo.svg for roots) +- [ ] Logo height is appropriate (250px for packages, 150px for roots) +- [ ] Badges are in a separate centered paragraph below logo +- [ ] Badge links point to correct URLs +- [ ] Version badge uses correct package name (with scope if applicable) +- [ ] License badge matches actual license in package +- [ ] CI badge points to correct workflow file + +## Common Mistakes + +1. **Missing logo**: Always add the header logo +2. **Wrong logo URL**: Use the raw.githubusercontent.com URL, not a relative path +3. **Badges in wrong order**: CI, then License, then Version +4. **Missing badge links**: Each badge image should be wrapped in an anchor tag +5. **Incorrect package name in version badge**: Must match exactly what's published to npm +6. **Using license badge for "All Rights Reserved"**: Only use for open source licenses + +## References + +- Logo assets: https://github.com/constructive-io/constructive/tree/main/assets +- Shields.io badges: https://shields.io/ +- Related skill: `pnpm-publishing` for publishing workflow +- Related skill: `pgpm` (`references/publishing.md`) for pgpm module publishing diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..2ebe50a --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,25 @@ +# AGENTS.md + +This file provides guidance to AI coding agents working with code in this repository. + +## Available Skills + +| Skill | Description | +|-------|-------------| +| **inquirerer-cli** | inquirerer CLI framework — interactive prompts, appStash state persistence, yanse terminal colors, and README formatting conventions. Use when building CLIs with inquirerer or formatting documentation. | + +## Skill Structure + +``` +.agents/skills/ + inquirerer-cli/ + SKILL.md # Skill definition + references/ # Detailed documentation + inquirerer-cli.md + inquirerer-cli-building.md + inquirerer-appstash.md + inquirerer-yanse.md + inquirerer-anti-patterns.md + readme-formatting.md + inquirerer-cli.zip # Packaged for distribution +``` From 4a0422f965191b288b47edbf74097d55f207738a Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Mon, 1 Jun 2026 00:09:17 +0000 Subject: [PATCH 2/2] fix: rename skill from inquirerer-cli to dev-utils The skill was named after one library when the repo has 30+ packages. Renamed to match the repo name and broadened the description to cover all packages (inquirerer, yanse, inflekt, appStash, etc.). --- .../{inquirerer-cli.zip => dev-utils.zip} | Bin 15820 -> 15858 bytes .../{inquirerer-cli => dev-utils}/SKILL.md | 12 +++++++----- .../references/inquirerer-anti-patterns.md | 0 .../references/inquirerer-appstash.md | 0 .../references/inquirerer-cli-building.md | 0 .../references/inquirerer-cli.md | 0 .../references/inquirerer-yanse.md | 0 .../references/readme-formatting.md | 0 AGENTS.md | 8 ++++---- 9 files changed, 11 insertions(+), 9 deletions(-) rename .agents/skills/{inquirerer-cli.zip => dev-utils.zip} (71%) rename .agents/skills/{inquirerer-cli => dev-utils}/SKILL.md (73%) rename .agents/skills/{inquirerer-cli => dev-utils}/references/inquirerer-anti-patterns.md (100%) rename .agents/skills/{inquirerer-cli => dev-utils}/references/inquirerer-appstash.md (100%) rename .agents/skills/{inquirerer-cli => dev-utils}/references/inquirerer-cli-building.md (100%) rename .agents/skills/{inquirerer-cli => dev-utils}/references/inquirerer-cli.md (100%) rename .agents/skills/{inquirerer-cli => dev-utils}/references/inquirerer-yanse.md (100%) rename .agents/skills/{inquirerer-cli => dev-utils}/references/readme-formatting.md (100%) diff --git a/.agents/skills/inquirerer-cli.zip b/.agents/skills/dev-utils.zip similarity index 71% rename from .agents/skills/inquirerer-cli.zip rename to .agents/skills/dev-utils.zip index 11ed867e166be590a1b3a4ceb249aca958fa944d..0a8ef982ed777480c4b15d451e3ee46d245f0b01 100644 GIT binary patch delta 2027 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 diff --git a/.agents/skills/inquirerer-cli/SKILL.md b/.agents/skills/dev-utils/SKILL.md similarity index 73% rename from .agents/skills/inquirerer-cli/SKILL.md rename to .agents/skills/dev-utils/SKILL.md index 93a4b7a..395281c 100644 --- a/.agents/skills/inquirerer-cli/SKILL.md +++ b/.agents/skills/dev-utils/SKILL.md @@ -1,20 +1,22 @@ --- -name: inquirerer-cli -description: "inquirerer CLI framework — interactive prompts, appStash state persistence, yanse terminal colors, and README formatting conventions. Use when building CLIs with inquirerer or formatting documentation. For pnpm workspace/publishing/monorepo management, see the constructive-pnpm skill instead." +name: dev-utils +description: "Developer utilities monorepo — inquirerer (interactive CLI prompts), yanse (terminal colors), appStash (state persistence), inflekt (string inflection), strfy-js (JSON stringify), clean-ansi, and 25+ other packages. Use when building CLIs with inquirerer, working with terminal colors, string inflection, or any package in the dev-utils repo." metadata: author: constructive-io version: "2.0.0" --- -# inquirerer CLI +# dev-utils -Build interactive CLI tools with the inquirerer framework: prompts, appStash state persistence, yanse terminal colors, and documentation formatting. +Developer utilities monorepo with 30+ packages for CLI tooling, parsing, and general-purpose TypeScript utilities. ## When to Apply Use this skill when: - Building interactive CLIs with `inquirerer` -- Formatting README and documentation files +- Working with terminal colors (`yanse`) +- Using string inflection (`inflekt`) +- Working with any package in the `constructive-io/dev-utils` repo **For pnpm workspace management, publishing, and monorepo configuration**, see the `constructive-pnpm` skill. diff --git a/.agents/skills/inquirerer-cli/references/inquirerer-anti-patterns.md b/.agents/skills/dev-utils/references/inquirerer-anti-patterns.md similarity index 100% rename from .agents/skills/inquirerer-cli/references/inquirerer-anti-patterns.md rename to .agents/skills/dev-utils/references/inquirerer-anti-patterns.md diff --git a/.agents/skills/inquirerer-cli/references/inquirerer-appstash.md b/.agents/skills/dev-utils/references/inquirerer-appstash.md similarity index 100% rename from .agents/skills/inquirerer-cli/references/inquirerer-appstash.md rename to .agents/skills/dev-utils/references/inquirerer-appstash.md diff --git a/.agents/skills/inquirerer-cli/references/inquirerer-cli-building.md b/.agents/skills/dev-utils/references/inquirerer-cli-building.md similarity index 100% rename from .agents/skills/inquirerer-cli/references/inquirerer-cli-building.md rename to .agents/skills/dev-utils/references/inquirerer-cli-building.md diff --git a/.agents/skills/inquirerer-cli/references/inquirerer-cli.md b/.agents/skills/dev-utils/references/inquirerer-cli.md similarity index 100% rename from .agents/skills/inquirerer-cli/references/inquirerer-cli.md rename to .agents/skills/dev-utils/references/inquirerer-cli.md diff --git a/.agents/skills/inquirerer-cli/references/inquirerer-yanse.md b/.agents/skills/dev-utils/references/inquirerer-yanse.md similarity index 100% rename from .agents/skills/inquirerer-cli/references/inquirerer-yanse.md rename to .agents/skills/dev-utils/references/inquirerer-yanse.md diff --git a/.agents/skills/inquirerer-cli/references/readme-formatting.md b/.agents/skills/dev-utils/references/readme-formatting.md similarity index 100% rename from .agents/skills/inquirerer-cli/references/readme-formatting.md rename to .agents/skills/dev-utils/references/readme-formatting.md diff --git a/AGENTS.md b/AGENTS.md index 2ebe50a..e808ed4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,18 +1,18 @@ # AGENTS.md -This file provides guidance to AI coding agents working with code in this repository. +This file provides guidance to AI agents working with the `constructive-io/dev-utils` monorepo. ## Available Skills | Skill | Description | |-------|-------------| -| **inquirerer-cli** | inquirerer CLI framework — interactive prompts, appStash state persistence, yanse terminal colors, and README formatting conventions. Use when building CLIs with inquirerer or formatting documentation. | +| **dev-utils** | Developer utilities — inquirerer (CLI prompts), yanse (terminal colors), appStash (state persistence), inflekt (string inflection), and 25+ other packages | ## Skill Structure ``` .agents/skills/ - inquirerer-cli/ + dev-utils/ SKILL.md # Skill definition references/ # Detailed documentation inquirerer-cli.md @@ -21,5 +21,5 @@ This file provides guidance to AI coding agents working with code in this reposi inquirerer-yanse.md inquirerer-anti-patterns.md readme-formatting.md - inquirerer-cli.zip # Packaged for distribution + dev-utils.zip # Packaged for distribution ```