@lousy-agents/cli 2.2.0 → 2.3.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.
Files changed (28) hide show
  1. package/api/copilot-with-fastify/biome.json +1 -1
  2. package/cli/copilot-with-citty/.devcontainer/devcontainer.json +76 -0
  3. package/cli/copilot-with-citty/.editorconfig +16 -0
  4. package/cli/copilot-with-citty/.github/ISSUE_TEMPLATE/feature-to-spec.yml +54 -0
  5. package/cli/copilot-with-citty/.github/copilot-instructions.md +228 -0
  6. package/cli/copilot-with-citty/.github/instructions/pipeline.instructions.md +92 -0
  7. package/cli/copilot-with-citty/.github/instructions/software-architecture.instructions.md +166 -0
  8. package/cli/copilot-with-citty/.github/instructions/spec.instructions.md +127 -0
  9. package/cli/copilot-with-citty/.github/instructions/test.instructions.md +157 -0
  10. package/cli/copilot-with-citty/.github/specs/README.md +84 -0
  11. package/cli/copilot-with-citty/.github/workflows/assign-copilot.yml +59 -0
  12. package/cli/copilot-with-citty/.github/workflows/ci.yml +67 -0
  13. package/cli/copilot-with-citty/.nvmrc +1 -0
  14. package/cli/copilot-with-citty/.vscode/extensions.json +13 -0
  15. package/cli/copilot-with-citty/.vscode/launch.json +25 -0
  16. package/cli/copilot-with-citty/.vscode/mcp.json +19 -0
  17. package/cli/copilot-with-citty/.yamllint +18 -0
  18. package/cli/copilot-with-citty/biome.json +31 -0
  19. package/cli/copilot-with-citty/package.json +29 -0
  20. package/cli/copilot-with-citty/tsconfig.json +28 -0
  21. package/cli/copilot-with-citty/vitest.config.ts +15 -0
  22. package/cli/copilot-with-citty/vitest.setup.ts +2 -0
  23. package/dist/index.js +224 -59
  24. package/dist/index.js.map +1 -1
  25. package/dist/mcp-server.js +32 -1
  26. package/dist/mcp-server.js.map +1 -1
  27. package/package.json +10 -9
  28. package/ui/copilot-with-react/biome.json +1 -1
@@ -0,0 +1,127 @@
1
+ ---
2
+ applyTo: "**/spec.md"
3
+ ---
4
+
5
+ # Spec Development Instructions
6
+
7
+ You are a product management partner helping define features for <product> targeting <customers>.
8
+
9
+ > Placeholder variables:
10
+ > - `<product>` is the name of the product or system for which this spec is being written.
11
+ > - `<customers>` describes the primary customer or user segments targeted by the spec.
12
+ > These placeholders may be automatically populated by your tooling; if not, replace them manually with the appropriate values before using this document.
13
+ ## Your Role
14
+
15
+ Act as a collaborative PM pair, not a passive assistant. This means:
16
+
17
+ - **Challenge assumptions** — Ask "why" before writing. Probe for the underlying problem.
18
+ - **Identify gaps** — Flag missing acceptance criteria, edge cases, and error states.
19
+ - **Guard scope** — Call out when a feature is too large for a single increment. Suggest phasing.
20
+ - **Propose value** — Don't wait to be asked. Assess and state which value types a feature delivers.
21
+ - **Ensure persona coverage** — Every spec must identify impacted personas. Push back if missing.
22
+
23
+ ## Collaboration Approach
24
+
25
+ Before writing or modifying a spec:
26
+
27
+ 1. Confirm you understand the problem being solved, not just the solution requested
28
+ 2. Ask clarifying questions if the request is ambiguous
29
+ 3. Identify which personas are affected and how
30
+ 4. Propose a value assessment
31
+ 5. Suggest scope boundaries if the feature feels too broad
32
+
33
+ When reviewing a spec:
34
+
35
+ 1. Verify all acceptance criteria use EARS notation
36
+ 2. Check that personas are explicitly named with impact described
37
+ 3. Confirm design aligns with engineering guidance
38
+ 4. Identify any missing error states or edge cases
39
+ 5. Assess whether tasks are appropriately sized for the coding agent
40
+
41
+ ## EARS Requirement Syntax
42
+
43
+ All acceptance criteria must use EARS (Easy Approach to Requirements Syntax) patterns:
44
+
45
+ | Pattern | Template | Use When |
46
+ |---------|----------|----------|
47
+ | Ubiquitous | The `<system>` shall `<response>` | Always true, no trigger |
48
+ | Event-driven | When `<trigger>`, the `<system>` shall `<response>` | Responding to an event |
49
+ | State-driven | While `<state>`, the `<system>` shall `<response>` | Active during a condition |
50
+ | Optional | Where `<feature>` is enabled, the `<system>` shall `<response>` | Configurable capability |
51
+ | Unwanted | If `<condition>`, then the `<system>` shall `<response>` | Error handling, edge cases |
52
+ | Complex | While `<state>`, when `<trigger>`, the `<system>` shall `<response>` | Combining conditions |
53
+
54
+ ### EARS Examples
55
+
56
+ ```markdown
57
+ - The CLI shall validate all input arguments before execution.
58
+ - When a user runs `init`, the system shall display a project type selection prompt.
59
+ - While verbose mode is enabled, the system shall log detailed debug information.
60
+ - Where custom configuration is provided, the system shall use it instead of defaults.
61
+ - If the configuration file is invalid, then the system shall display a validation error with details.
62
+ - While strict mode is enabled, when an unknown argument is provided, the system shall reject the command.
63
+ ```
64
+
65
+ ## User Story Format
66
+
67
+ ```markdown
68
+ ### Story: <Concise Title>
69
+
70
+ As a **<persona>**,
71
+ I want **<capability>**,
72
+ so that I can **<outcome/problem solved>**.
73
+
74
+ #### Acceptance Criteria
75
+
76
+ - When <trigger>, the <system> shall <response>
77
+ - While <state>, the <system> shall <response>
78
+ - If <error condition>, then the <system> shall <response>
79
+
80
+ #### Notes
81
+
82
+ <Context, constraints, or open questions>
83
+ ```
84
+
85
+ ## Spec File Structure
86
+
87
+ A spec has three sections that flow into each other:
88
+
89
+ 1. **Requirements** — What we're building and why (human and agent context)
90
+ 2. **Design** — How it fits into the system (agent context for implementation)
91
+ 3. **Tasks** — Discrete units of work (directly assignable to coding agent)
92
+
93
+ ## Task Design Guidelines
94
+
95
+ ### Size
96
+
97
+ - Completable in one agent session (~1-3 files, ~200-300 lines changed)
98
+ - If a task feels too large, split it
99
+ - If you have more than 7-10 tasks, split the feature into phases
100
+
101
+ ### Clarity
102
+
103
+ - **Objective** — One sentence, action-oriented
104
+ - **Context** — Explains why; agents make better decisions with intent
105
+ - **Affected files** — Tells the agent where to focus
106
+ - **Requirements** — Links back to specific acceptance criteria
107
+
108
+ ### Verification
109
+
110
+ Every task must include verification steps the agent can run:
111
+
112
+ ```markdown
113
+ **Verification**:
114
+ - [ ] `npm test` passes
115
+ - [ ] `npm run lint` passes
116
+ - [ ] New command returns expected output for valid input
117
+ - [ ] New command returns error message for invalid input
118
+ ```
119
+
120
+ ## Diagram Requirements
121
+
122
+ All diagrams in specs must use **Mermaid** syntax for consistency and GitHub rendering support.
123
+
124
+ ## Related Files
125
+
126
+ - `.github/ISSUE_TEMPLATE/feature-to-spec.yml` — Issue template for creating specs
127
+ - `.github/workflows/assign-copilot.yml` — Workflow for auto-assigning Copilot
@@ -0,0 +1,157 @@
1
+ ---
2
+ applyTo: "src/**/*.{test,spec}.ts"
3
+ ---
4
+
5
+ # Testing Conventions for CLI
6
+
7
+ ## MANDATORY: After Test Changes
8
+
9
+ Run `npm test` after modifying or creating tests to verify all tests pass.
10
+
11
+ ## Test File Structure
12
+
13
+ Use this structure for all test files:
14
+
15
+ ```typescript
16
+ import { describe, it, expect } from 'vitest';
17
+
18
+ describe('ComponentName', () => {
19
+ describe('when [condition]', () => {
20
+ it('should [expected behavior]', () => {
21
+ // Arrange
22
+ const input = 'test-value';
23
+
24
+ // Act
25
+ const result = functionUnderTest(input);
26
+
27
+ // Assert
28
+ expect(result).toBe('expected-value');
29
+ });
30
+ });
31
+ });
32
+ ```
33
+
34
+ ## Test Data
35
+
36
+ - Use Chance.js to generate random test data when actual input values are not important.
37
+ - Generate Chance.js data that produces readable assertion failure messages.
38
+ - Use simple strings or numbers - avoid overly complex Chance.js configurations.
39
+
40
+ ## Test Design Rules
41
+
42
+ 1. Follow the Arrange-Act-Assert (AAA) pattern for ALL tests.
43
+ 2. Use spec-style tests with `describe` and `it` blocks.
44
+ 3. Write test descriptions as user stories: "should [do something] when [condition]".
45
+ 4. Focus on behavior, NOT implementation details.
46
+ 5. Extract fixture values to variables - NEVER hardcode values in both setup and assertions.
47
+ 6. Use `msw` to mock external HTTP APIs - do NOT mock fetch directly.
48
+ 7. Avoid mocking third-party dependencies when possible.
49
+ 8. Tests MUST be isolated - no shared state between tests.
50
+ 9. Tests MUST be deterministic - same result every run.
51
+ 10. Tests MUST run identically locally and in CI.
52
+ 11. NEVER use partial mocks.
53
+ 12. Test ALL conditional paths with meaningful assertions.
54
+ 13. Test unhappy paths and edge cases, not just happy paths.
55
+ 14. Every assertion should explain the expected behavior.
56
+ 15. Write tests that would FAIL if production code regressed.
57
+ 16. **NEVER export functions, methods, or variables from production code solely for testing purposes.**
58
+ 17. **NEVER use module-level mutable state for dependency injection in production code.**
59
+
60
+ ## Dependency Injection for Testing
61
+
62
+ When you need to inject dependencies for testing:
63
+
64
+ - **DO** use constructor parameters, function parameters, or factory functions.
65
+ - **DO** pass test doubles through the existing public API of the code under test.
66
+ - **DO NOT** export special test-only functions like `_setTestDependencies()` or `_resetTestDependencies()`.
67
+ - **DO NOT** modify module-level state from tests.
68
+
69
+ ### Good Example (Dependency Injection via Factory Function)
70
+
71
+ ```typescript
72
+ // Production code - use-cases/process-input.ts
73
+ export interface InputReader {
74
+ read(source: string): Promise<string>;
75
+ }
76
+
77
+ export function createInputProcessor(reader: InputReader) {
78
+ return {
79
+ async execute(source: string) {
80
+ const content = await reader.read(source);
81
+ if (!content.trim()) {
82
+ throw new Error('Empty input');
83
+ }
84
+ return content;
85
+ }
86
+ };
87
+ }
88
+
89
+ // Test code
90
+ it("should process valid input", async () => {
91
+ const mockReader = {
92
+ read: vi.fn().mockResolvedValue("valid content")
93
+ };
94
+ const processor = createInputProcessor(mockReader);
95
+
96
+ const result = await processor.execute("source.txt");
97
+
98
+ expect(result).toBe("valid content");
99
+ expect(mockReader.read).toHaveBeenCalledWith("source.txt");
100
+ });
101
+ ```
102
+
103
+ ### Bad Example (Test-Only Exports)
104
+
105
+ ```typescript
106
+ // ❌ BAD: Production code
107
+ let _readerOverride: any;
108
+
109
+ export function _setTestDependencies(deps: any) {
110
+ _readerOverride = deps.reader;
111
+ }
112
+
113
+ export function processInput(source: string) {
114
+ const reader = _readerOverride || defaultReader;
115
+ return reader.read(source);
116
+ }
117
+
118
+ // ❌ BAD: Test code
119
+ import { _setTestDependencies, processInput } from "./process-input";
120
+
121
+ beforeEach(() => {
122
+ _setTestDependencies({ reader: mockReader });
123
+ });
124
+ ```
125
+
126
+ ## CLI Command Testing
127
+
128
+ Test citty commands by providing mock context:
129
+
130
+ ```typescript
131
+ import { describe, it, expect, vi } from 'vitest';
132
+ import { myCommand } from './my-command';
133
+
134
+ describe('My Command', () => {
135
+ describe('given valid arguments', () => {
136
+ it('should execute the expected action', async () => {
137
+ // Arrange
138
+ const mockPrompt = vi.fn().mockResolvedValue('user-input');
139
+
140
+ // Act
141
+ await myCommand.run({
142
+ rawArgs: ['--name', 'test'],
143
+ args: { _: [], name: 'test' },
144
+ cmd: myCommand,
145
+ data: { prompt: mockPrompt },
146
+ });
147
+
148
+ // Assert
149
+ expect(mockPrompt).not.toHaveBeenCalled();
150
+ });
151
+ });
152
+ });
153
+ ```
154
+
155
+ ## Dependencies
156
+
157
+ Install new test dependencies using: `npm install <package>@<exact-version>`
@@ -0,0 +1,84 @@
1
+ # Specifications Directory
2
+
3
+ This directory contains feature specifications created through the spec-driven development workflow.
4
+
5
+ ## Workflow Overview
6
+
7
+ 1. **Create a Spec Issue** — Use the "Copilot Feature To Spec" issue template to define your feature
8
+ 2. **Auto-Assignment** — Issues with the `copilot-ready` label automatically trigger Copilot assignment
9
+ 3. **Spec Creation** — Copilot creates a structured specification in this directory
10
+ 4. **Implementation** — Follow the tasks in the spec to implement the feature
11
+
12
+ ## Spec File Structure
13
+
14
+ Each spec follows this structure:
15
+
16
+ ```markdown
17
+ # Feature: <name>
18
+
19
+ ## Problem Statement
20
+ <2-3 sentences describing the problem>
21
+
22
+ ## Personas
23
+ | Persona | Impact | Notes |
24
+ |---------|--------|-------|
25
+
26
+ ## Value Assessment
27
+ - **Primary value**: <type> — <explanation>
28
+
29
+ ## User Stories
30
+
31
+ ### Story 1: <Title>
32
+ As a **<persona>**,
33
+ I want **<capability>**,
34
+ so that I can **<outcome>**.
35
+
36
+ #### Acceptance Criteria
37
+ - When <trigger>, the <system> shall <response>
38
+
39
+ ---
40
+
41
+ ## Design
42
+
43
+ ### Components Affected
44
+ ### Dependencies
45
+ ### Open Questions
46
+
47
+ ---
48
+
49
+ ## Tasks
50
+
51
+ ### Task 1: <Title>
52
+ **Objective**: ...
53
+ **Verification**: ...
54
+ ```
55
+
56
+ ## EARS Syntax for Acceptance Criteria
57
+
58
+ Use EARS (Easy Approach to Requirements Syntax) patterns:
59
+
60
+ | Pattern | Template | Use When |
61
+ |---------|----------|----------|
62
+ | Ubiquitous | The `<system>` shall `<response>` | Always true |
63
+ | Event-driven | When `<trigger>`, the `<system>` shall `<response>` | Responding to event |
64
+ | State-driven | While `<state>`, the `<system>` shall `<response>` | During a condition |
65
+ | Optional | Where `<feature>` is enabled, the `<system>` shall `<response>` | Configurable capability |
66
+ | Unwanted | If `<condition>`, then the `<system>` shall `<response>` | Error handling |
67
+ | Complex | While `<state>`, when `<trigger>`, the `<system>` shall `<response>` | Combining conditions |
68
+
69
+ ### Examples
70
+
71
+ ```markdown
72
+ - The CLI shall validate all input arguments
73
+ - When a user runs a command, the system shall display the result
74
+ - While verbose mode is enabled, the system shall log debug information
75
+ - Where custom configuration is provided, the system shall use it instead of defaults
76
+ - If the input is malformed, then the system shall return a descriptive error
77
+ - While strict mode is enabled, when an unknown argument is provided, the system shall reject the command
78
+ ```
79
+
80
+ ## Related Files
81
+
82
+ - `.github/ISSUE_TEMPLATE/feature-to-spec.yml` — Issue template for creating specs
83
+ - `.github/workflows/assign-copilot.yml` — Workflow for auto-assigning Copilot
84
+ - `.github/instructions/spec.instructions.md` — Detailed instructions for spec writing
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: Auto-Assign Copilot on Spec Issues
3
+
4
+ on:
5
+ issues:
6
+ types: [opened, edited]
7
+
8
+ permissions:
9
+ issues: write
10
+
11
+ jobs:
12
+ assign-agent:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: Assign and Instruct Copilot
16
+ uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
17
+ with:
18
+ script: |
19
+ const issue = context.payload.issue;
20
+
21
+ // Check if issue has the copilot-ready label
22
+ const hasCopilotLabel = issue.labels.some(label => label.name === 'copilot-ready');
23
+
24
+ if (!hasCopilotLabel) {
25
+ console.log("Issue does not have 'copilot-ready' label. Skipping.");
26
+ return;
27
+ }
28
+
29
+ const body = issue.body || "";
30
+ const pattern = /### Extra Instructions\s+([\s\S]*?)(?=\n###|$)/;
31
+ const match = body.match(pattern);
32
+
33
+ // Always mention @copilot to trigger assignment and provide context
34
+ let comment = "@copilot";
35
+
36
+ if (match && match[1].trim().length > 0) {
37
+ let instructions = match[1].trim();
38
+
39
+ // Basic sanitization: limit length to prevent overly long comments
40
+ const MAX_LENGTH = 2000;
41
+ if (instructions.length > MAX_LENGTH) {
42
+ instructions = instructions.slice(0, MAX_LENGTH) + "\n\n[Instructions truncated]";
43
+ }
44
+
45
+ comment = `@copilot ${instructions}`;
46
+ console.log("Found extra instructions, mentioning Copilot with instructions.");
47
+ } else {
48
+ comment = "@copilot Please work on this issue according to the specification provided.";
49
+ console.log("No extra instructions found, mentioning Copilot with default message.");
50
+ }
51
+
52
+ await github.rest.issues.createComment({
53
+ owner: context.repo.owner,
54
+ repo: context.repo.repo,
55
+ issue_number: issue.number,
56
+ body: comment
57
+ });
58
+
59
+ console.log("Successfully mentioned Copilot in issue comment.");
@@ -0,0 +1,67 @@
1
+ ---
2
+ name: CI
3
+
4
+ on:
5
+ push:
6
+ branches: [main]
7
+ pull_request:
8
+ branches: [main]
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ jobs:
14
+ lint:
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - name: Checkout
18
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
19
+
20
+ - name: Setup Node.js
21
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
22
+ with:
23
+ node-version-file: '.nvmrc'
24
+ cache: 'npm'
25
+
26
+ - name: Install dependencies
27
+ run: npm ci
28
+
29
+ - name: Lint
30
+ run: npx biome check
31
+
32
+ test:
33
+ runs-on: ubuntu-latest
34
+ steps:
35
+ - name: Checkout
36
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
37
+
38
+ - name: Setup Node.js
39
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
40
+ with:
41
+ node-version-file: '.nvmrc'
42
+ cache: 'npm'
43
+
44
+ - name: Install dependencies
45
+ run: npm ci
46
+
47
+ - name: Run tests
48
+ run: npm test
49
+
50
+ build:
51
+ runs-on: ubuntu-latest
52
+ needs: [lint, test]
53
+ steps:
54
+ - name: Checkout
55
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
56
+
57
+ - name: Setup Node.js
58
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
59
+ with:
60
+ node-version-file: '.nvmrc'
61
+ cache: 'npm'
62
+
63
+ - name: Install dependencies
64
+ run: npm ci
65
+
66
+ - name: Build
67
+ run: npm run build
@@ -0,0 +1 @@
1
+ v24.13.0
@@ -0,0 +1,13 @@
1
+ {
2
+ "recommendations": [
3
+ "biomejs.biome",
4
+ "editorconfig.editorconfig",
5
+ "vitest.explorer",
6
+ "ms-vscode-remote.remote-containers",
7
+ "GitHub.codespaces",
8
+ "GitHub.Copilot",
9
+ "GitHub.Copilot-Chat",
10
+ "GitHub.github-vscode-theme",
11
+ "redhat.vscode-yaml"
12
+ ]
13
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "version": "0.2.0",
3
+ "configurations": [
4
+ {
5
+ "name": "Start CLI Locally",
6
+ "type": "node",
7
+ "request": "launch",
8
+ "runtimeExecutable": "npm",
9
+ "runtimeArgs": ["run", "dev"],
10
+ "console": "integratedTerminal",
11
+ "cwd": "${workspaceFolder}"
12
+ },
13
+ {
14
+ "name": "Debug Current Test File",
15
+ "type": "node",
16
+ "request": "launch",
17
+ "autoAttachChildProcesses": true,
18
+ "skipFiles": ["<node_internals>/**", "**/node_modules/**"],
19
+ "program": "${workspaceFolder}/node_modules/vitest/vitest.mjs",
20
+ "args": ["run", "${relativeFile}"],
21
+ "smartStep": true,
22
+ "console": "integratedTerminal"
23
+ }
24
+ ]
25
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "servers": {
3
+ "context7": {
4
+ "type": "stdio",
5
+ "command": "npx",
6
+ "args": ["-y", "@upstash/context7-mcp"]
7
+ },
8
+ "sequential-thinking": {
9
+ "type": "stdio",
10
+ "command": "npx",
11
+ "args": ["-y", "@modelcontextprotocol/server-sequential-thinking"]
12
+ },
13
+ "lousy-agents": {
14
+ "type": "stdio",
15
+ "command": "npx",
16
+ "args": ["-y", "@lousy-agents/cli", "mcp"]
17
+ }
18
+ }
19
+ }
@@ -0,0 +1,18 @@
1
+ extends: default
2
+
3
+ ignore: |
4
+ node_modules/
5
+ dist/
6
+
7
+ rules:
8
+ indentation:
9
+ spaces: 2
10
+ indent-sequences: true
11
+ line-length:
12
+ max: 120
13
+ level: warning
14
+
15
+ document-start: disable
16
+ truthy: disable
17
+ comments:
18
+ min-spaces-from-content: 1
@@ -0,0 +1,31 @@
1
+ {
2
+ "root": false,
3
+ "$schema": "https://biomejs.dev/schemas/2.3.13/schema.json",
4
+ "vcs": {
5
+ "enabled": true,
6
+ "clientKind": "git",
7
+ "useIgnoreFile": true
8
+ },
9
+ "files": {
10
+ "ignoreUnknown": false
11
+ },
12
+ "formatter": {
13
+ "enabled": true,
14
+ "indentStyle": "space",
15
+ "indentWidth": 4
16
+ },
17
+ "linter": {
18
+ "enabled": true,
19
+ "rules": {
20
+ "recommended": true,
21
+ "style": {
22
+ "useConsistentCurlyBraces": "error"
23
+ }
24
+ }
25
+ },
26
+ "javascript": {
27
+ "formatter": {
28
+ "quoteStyle": "double"
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "<%= it.projectName %>",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "tsx watch src/index.ts",
8
+ "build": "tsc",
9
+ "start": "node dist/index.js",
10
+ "test": "vitest run",
11
+ "lint": "biome check .",
12
+ "lint:fix": "biome check --write .",
13
+ "lint:workflows": "actionlint",
14
+ "lint:yaml": "yamllint ."
15
+ },
16
+ "dependencies": {
17
+ "citty": "0.2.0",
18
+ "consola": "3.4.2",
19
+ "zod": "3.25.56"
20
+ },
21
+ "devDependencies": {
22
+ "@biomejs/biome": "2.3.8",
23
+ "@types/node": "22.16.4",
24
+ "chance": "1.1.12",
25
+ "tsx": "4.20.3",
26
+ "typescript": "5.8.3",
27
+ "vitest": "4.0.15"
28
+ }
29
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2022"],
5
+ "module": "NodeNext",
6
+ "moduleResolution": "NodeNext",
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true,
10
+ "forceConsistentCasingInFileNames": true,
11
+ "outDir": "./dist",
12
+ "rootDir": "./src",
13
+ "declaration": true,
14
+ "declarationMap": true,
15
+ "sourceMap": true,
16
+ "resolveJsonModule": true,
17
+ "noEmit": false,
18
+ "isolatedModules": true,
19
+ "noUnusedLocals": true,
20
+ "noUnusedParameters": true,
21
+ "noFallthroughCasesInSwitch": true,
22
+ "exactOptionalPropertyTypes": true,
23
+ "noImplicitReturns": true,
24
+ "noUncheckedIndexedAccess": true
25
+ },
26
+ "include": ["src/**/*.ts"],
27
+ "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"]
28
+ }
@@ -0,0 +1,15 @@
1
+ import { defineConfig } from "vitest/config";
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ globals: true,
6
+ environment: "node",
7
+ setupFiles: ["./vitest.setup.ts"],
8
+ include: ["src/**/*.test.ts"],
9
+ coverage: {
10
+ provider: "v8",
11
+ reporter: ["text", "json", "html"],
12
+ exclude: ["node_modules/", "dist/", "**/*.test.ts"],
13
+ },
14
+ },
15
+ });
@@ -0,0 +1,2 @@
1
+ // Vitest setup file for CLI tests
2
+ // Add any global test setup here