@lousy-agents/cli 1.0.1 → 1.0.5

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": "@lousy-agents/cli",
3
- "version": "1.0.1",
3
+ "version": "1.0.5",
4
4
  "description": "CLI scaffolding tool that sets up projects with structure, instructions, and feedback loops for AI coding assistants",
5
5
  "type": "module",
6
6
  "repository": {
@@ -23,14 +23,17 @@
23
23
  "vibe-coding"
24
24
  ],
25
25
  "publishConfig": {
26
- "access": "public"
26
+ "access": "public",
27
+ "provenance": true
27
28
  },
28
29
  "files": [
29
- "dist"
30
+ "dist",
31
+ "ui"
30
32
  ],
31
33
  "bin": {
32
- "lousy-agents": "./dist/index.js",
33
- "lousy-agents-mcp": "./dist/mcp-server.js"
34
+ "cli": "dist/index.js",
35
+ "lousy-agents": "dist/index.js",
36
+ "lousy-agents-mcp": "dist/mcp-server.js"
34
37
  },
35
38
  "scripts": {
36
39
  "dev": "tsx src/index.ts",
@@ -53,7 +56,7 @@
53
56
  "zod": "4.3.6"
54
57
  },
55
58
  "devDependencies": {
56
- "@biomejs/biome": "2.3.12",
59
+ "@biomejs/biome": "2.3.13",
57
60
  "@types/chance": "1.1.7",
58
61
  "@types/node": "24.10.4",
59
62
  "chance": "1.1.13",
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "<%= it.projectName %>",
3
+ "image": "mcr.microsoft.com/devcontainers/javascript-node:24-bookworm",
4
+ "features": {
5
+ "ghcr.io/devcontainers/features/github-cli:1": {
6
+ "version": "2.83.2"
7
+ },
8
+ "ghcr.io/rocker-org/devcontainer-features/apt-packages:1": {
9
+ "packages": "libnss3, libnspr4, libatk1.0-0, libatk-bridge2.0-0, libcups2, libdrm2, libdbus-1-3, libatspi2.0-0, libxcomposite1, libxdamage1, libxfixes3, libxrandr2, libgbm1, libxkbcommon0, libasound2, yamllint, shellcheck",
10
+ "upgradePackages": true
11
+ },
12
+ "ghcr.io/devcontainers/features/docker-outside-of-docker:1": {
13
+ "version": "27.5.1"
14
+ },
15
+ "ghcr.io/devcontainers-extra/features/actionlint:1": {
16
+ "version": "1.7.9"
17
+ }
18
+ },
19
+ "forwardPorts": [3000],
20
+ "portsAttributes": {
21
+ "3000": {
22
+ "label": "Application",
23
+ "onAutoForward": "notify"
24
+ }
25
+ },
26
+ "postCreateCommand": "npm cache add @upstash/context7-mcp @modelcontextprotocol/server-sequential-thinking",
27
+ "waitFor": "postCreateCommand",
28
+ "remoteUser": "node",
29
+ "customizations": {
30
+ "vscode": {
31
+ "extensions": [
32
+ "biomejs.biome",
33
+ "dbaeumer.vscode-eslint",
34
+ "editorconfig.editorconfig",
35
+ "vitest.explorer",
36
+ "ms-vscode-remote.remote-containers",
37
+ "GitHub.codespaces",
38
+ "ms-vscode.makefile-tools",
39
+ "GitHub.Copilot",
40
+ "GitHub.Copilot-Chat",
41
+ "GitHub.github-vscode-theme",
42
+ "redhat.vscode-yaml"
43
+ ],
44
+ "settings": {
45
+ "editor.formatOnSave": true,
46
+ "editor.defaultFormatter": "biomejs.biome",
47
+ "[json]": {
48
+ "editor.defaultFormatter": "biomejs.biome"
49
+ },
50
+ "[javascript]": {
51
+ "editor.defaultFormatter": "biomejs.biome"
52
+ },
53
+ "[typescript]": {
54
+ "editor.defaultFormatter": "biomejs.biome"
55
+ },
56
+ "[yaml]": {
57
+ "editor.defaultFormatter": "redhat.vscode-yaml",
58
+ "editor.tabSize": 2
59
+ },
60
+ "editor.codeActionsOnSave": {
61
+ "source.fixAll.eslint": "explicit"
62
+ },
63
+ "vitest.enable": true,
64
+ "vitest.commandLine": "vitest",
65
+ "github.copilot.chat.agent.model": "claude-sonnet-4.5",
66
+ "github.copilot.chat.ask.model": "claude-sonnet-4.5",
67
+ "yaml.schemas": {
68
+ "https://json.schemastore.org/github-workflow.json": ".github/workflows/*.yml"
69
+ },
70
+ "github.copilot.chat.mcp.enabled": true
71
+ },
72
+ "mcp": {
73
+ "servers": {
74
+ "context7": {
75
+ "type": "stdio",
76
+ "command": "npx",
77
+ "args": ["-y", "@upstash/context7-mcp"]
78
+ },
79
+ "sequential-thinking": {
80
+ "command": "npx",
81
+ "args": [
82
+ "-y",
83
+ "@modelcontextprotocol/server-sequential-thinking"
84
+ ]
85
+ }
86
+ }
87
+ }
88
+ }
89
+ }
90
+ }
@@ -0,0 +1,16 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ indent_size = 4
7
+ indent_style = space
8
+ insert_final_newline = true
9
+ max_line_length = off
10
+ trim_trailing_whitespace = true
11
+
12
+ [{*.json}]
13
+ indent_size = 4
14
+
15
+ [{*.yaml,*.yml}]
16
+ indent_size = 2
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: Copilot Feature To Spec
3
+ description: Create a spec for the Copilot coding agent.
4
+ title: "[Spec]: "
5
+ labels: ["copilot-ready", "enhancement"]
6
+ body:
7
+ - type: markdown
8
+ attributes:
9
+ value: |
10
+ ## Copilot Specification
11
+ Please fill out the details below.
12
+ This structure is parsed by the Copilot Agent.
13
+
14
+ - type: textarea
15
+ id: context
16
+ attributes:
17
+ label: Context & Goal
18
+ description: What is the goal? What part of the codebase?
19
+ placeholder: |
20
+ We need to add a rate-limiting middleware to the API
21
+ gateway...
22
+ validations:
23
+ required: true
24
+
25
+ - type: textarea
26
+ id: acceptance-criteria
27
+ attributes:
28
+ label: Acceptance Criteria
29
+ description: How will we verify this is done?
30
+ placeholder: |
31
+ I run `node dist/index.js init`.
32
+ I see a .github directory with ...
33
+ validations:
34
+ required: true
35
+
36
+ # ---------------------------------------------------------
37
+ # This section triggers the GitHub Script integration
38
+ # ---------------------------------------------------------
39
+ - type: textarea
40
+ id: extra-instructions
41
+ attributes:
42
+ label: Extra Instructions
43
+ description: Specific prompt engineering for the agent. This will be posted as a comment to guide the bot.
44
+ value: |
45
+ 1. Review .github/instructions/spec.instructions.md for more details and use this as your guide for the feature specification.
46
+ 2. Ensure you review all other repository instructions before starting work to understand engineering requirements.
47
+ 3. Create your final spec output in the .github/specs directory and ensure requirements are captured in the EARS format.
48
+ 4. Create a data flow diagram and sequence diagram to illustrate the feature's operation.
49
+ 5. Break down the feature into manageable tasks with clear descriptions.
50
+ 6. As you complete each task in the spec, mark the checkboxes as complete in the spec file using [x] notation.
51
+ 7. If you need to make assumptions, ask questions on the issue.
52
+ 8. Use the diagrams to inform your implementation plan.
53
+ validations:
54
+ required: false
@@ -0,0 +1,281 @@
1
+ ---
2
+ applyTo: "**"
3
+ ---
4
+
5
+ # Next.js TDD Application
6
+
7
+ A Next.js TypeScript application following Test-Driven Development, Clean Architecture, and strict validation workflows.
8
+
9
+ ## Commands
10
+
11
+ Run `nvm use` before any npm command. During development, use file-scoped commands for faster feedback, and run the full validation suite (`npx biome check && npm test && npm run build`) before commits.
12
+
13
+ ```bash
14
+ # ALWAYS run first
15
+ nvm use
16
+
17
+ # Core commands
18
+ npm install # Install deps (updates package-lock.json)
19
+ npm test # Run tests (vitest)
20
+ npm run build # Production build
21
+ npx biome check # Lint check
22
+ npx biome check --write # Auto-fix lint/format
23
+
24
+ # File-scoped (faster feedback)
25
+ npx biome check path/to/file.ts
26
+ npm test path/to/file.test.ts
27
+
28
+ # Validation suite (run before commits)
29
+ npx biome check && npm test && npm run build
30
+
31
+ # Other
32
+ npm audit # Security check
33
+ npm run lint:workflows # Validate GitHub Actions (actionlint)
34
+ npm run lint:yaml # Validate YAML (yamllint)
35
+ ```
36
+
37
+ ## Workflow: TDD Required
38
+
39
+ Follow this exact sequence for ALL code changes. Work in small increments — make one change at a time and validate before proceeding.
40
+
41
+ 1. **Research**: Search codebase for existing patterns, components, utilities. Use Context7 MCP tools for library/API documentation.
42
+ 2. **Write failing test**: Create test describing desired behavior
43
+ 3. **Verify failure**: Run `npm test` — confirm clear failure message
44
+ 4. **Implement minimal code**: Write just enough to pass
45
+ 5. **Verify pass**: Run `npm test` — confirm pass
46
+ 6. **Refactor**: Clean up, remove duplication, keep tests green
47
+ 7. **Validate**: `npx biome check && npm test && npm run build`
48
+
49
+ Task is NOT complete until all validation passes.
50
+
51
+ ## Tech Stack
52
+
53
+ - **Framework**: Next.js (React) — follow Next.js conventions
54
+ - **Language**: TypeScript (strict mode)
55
+ - **Validation**: Zod for runtime validation of external data
56
+ - **Testing**: Vitest (never Jest), MSW for HTTP mocking, Chance.js for test fixtures
57
+ - **Linting**: Biome (never ESLint/Prettier separately)
58
+ - **Logging**: Pino with JSON format and child loggers
59
+ - **HTTP**: fetch API only
60
+ - **Architecture**: Clean Architecture principles
61
+
62
+ ## Project Structure
63
+
64
+ ```
65
+ .github/ GitHub Actions workflows
66
+ src/ Application source code
67
+ components/ React components
68
+ pages/ Next.js pages and routes
69
+ lib/ Utilities and helpers
70
+ tests/ Test files (mirror src/ structure)
71
+ scripts/ Build, deploy, and test scripts
72
+ .nvmrc Node.js version (latest LTS)
73
+ ```
74
+
75
+ ## Code Style
76
+
77
+ ```typescript
78
+ import { z } from 'zod';
79
+
80
+ // Define schema for runtime validation
81
+ const UserSchema = z.object({
82
+ id: z.string(),
83
+ name: z.string(),
84
+ });
85
+
86
+ type User = z.infer<typeof UserSchema>;
87
+
88
+ // ✅ Good - small, typed, single purpose, descriptive names, runtime validation
89
+ async function fetchUserById(userId: string): Promise<User> {
90
+ if (!userId) {
91
+ throw new Error('User ID required');
92
+ }
93
+
94
+ const response = await fetch(`/api/users/${userId}`);
95
+
96
+ if (!response.ok) {
97
+ throw new Error(`Failed to fetch user: ${response.status}`);
98
+ }
99
+
100
+ const data: unknown = await response.json();
101
+ return UserSchema.parse(data);
102
+ }
103
+
104
+ // ❌ Bad - untyped, type assertion on external data, no validation, multiple responsibilities, impure (side effects: global state mutation)
105
+ async function doStuff(x) {
106
+ console.log('fetching');
107
+ globalState.loading = true;
108
+ const response = await fetch('/api/users/' + x);
109
+ return response.json() as User;
110
+ }
111
+ ```
112
+
113
+ **Rules:**
114
+ - Always use TypeScript type hints
115
+ - Use descriptive names for variables, functions, and modules
116
+ - Functions must be small and have single responsibility
117
+ - Avoid god functions and classes — break into smaller, focused units
118
+ - Avoid repetitive code — extract reusable functions
119
+ - Extract functions when there are multiple code paths
120
+ - Favor immutability and pure functions
121
+ - Avoid temporal coupling
122
+ - Keep cyclomatic complexity low
123
+ - Remove all unused imports and variables
124
+ - Validate external data at runtime with Zod — never use type assertions (`as Type`) on API responses
125
+ - Always check `response.ok` when using fetch
126
+ - Run lint and tests after EVERY change
127
+
128
+ ## Testing Standards
129
+
130
+ Tests are executable documentation. Use Arrange-Act-Assert pattern. Mock HTTP with MSW. Generate test fixtures with Chance.js.
131
+
132
+ ```typescript
133
+ import Chance from 'chance';
134
+ import { http, HttpResponse } from 'msw';
135
+ import { setupServer } from 'msw/node';
136
+ import { beforeAll, afterAll, afterEach, describe, it, expect } from 'vitest';
137
+ import { fetchUserById } from './user-service';
138
+
139
+ const chance = new Chance();
140
+ const server = setupServer();
141
+
142
+ beforeAll(() => server.listen());
143
+ afterEach(() => server.resetHandlers());
144
+ afterAll(() => server.close());
145
+
146
+ // ✅ Good - describes behavior, reads like documentation, uses generated fixtures
147
+ describe('User retrieval', () => {
148
+ describe('given a valid user ID', () => {
149
+ it('returns the user details from the API', async () => {
150
+ // Arrange
151
+ const userId = chance.guid();
152
+ const expectedUser = { id: userId, name: chance.name() };
153
+ server.use(
154
+ http.get(`/api/users/${userId}`, () => {
155
+ return HttpResponse.json(expectedUser);
156
+ })
157
+ );
158
+
159
+ // Act
160
+ const result = await fetchUserById(userId);
161
+
162
+ // Assert
163
+ expect(result).toEqual(expectedUser);
164
+ });
165
+ });
166
+
167
+ describe('given an empty user ID', () => {
168
+ it('rejects with a validation error', async () => {
169
+ // Arrange - no server setup needed, validation happens before fetch
170
+
171
+ // Act & Assert
172
+ await expect(fetchUserById('')).rejects.toThrow('User ID required');
173
+ });
174
+ });
175
+
176
+ describe('given a non-existent user ID', () => {
177
+ it('rejects with an error containing the status code', async () => {
178
+ // Arrange
179
+ const userId = chance.guid();
180
+ server.use(
181
+ http.get(`/api/users/${userId}`, () => {
182
+ return new HttpResponse(null, { status: 404 });
183
+ })
184
+ );
185
+
186
+ // Act & Assert
187
+ await expect(fetchUserById(userId)).rejects.toThrow(
188
+ 'Failed to fetch user: 404'
189
+ );
190
+ });
191
+ });
192
+
193
+ describe('given an invalid response shape', () => {
194
+ it('rejects with a validation error', async () => {
195
+ // Arrange
196
+ const userId = chance.guid();
197
+ server.use(
198
+ http.get(`/api/users/${userId}`, () => {
199
+ return HttpResponse.json({ invalid: 'data' });
200
+ })
201
+ );
202
+
203
+ // Act & Assert
204
+ await expect(fetchUserById(userId)).rejects.toThrow();
205
+ });
206
+ });
207
+ });
208
+
209
+ // ❌ Bad - implementation-focused, hardcoded values, duplicated test data
210
+ describe('fetchUserById', () => {
211
+ it('works', async () => {
212
+ const user = { id: '123', name: 'Alice' };
213
+ server.use(
214
+ http.get('/api/users/123', () => HttpResponse.json(user))
215
+ );
216
+ const result = await fetchUserById('123'); // duplicated '123' across arrange/act/assert
217
+ expect(result).toEqual(user);
218
+ });
219
+ });
220
+ ```
221
+
222
+ **Rules:**
223
+ - Tests are executable documentation — describe behavior, not implementation
224
+ - Name `describe` blocks for features/scenarios, not function names
225
+ - Name `it` blocks as specifications that read as complete sentences
226
+ - Use nested `describe` blocks for "given/when" context
227
+ - Use Chance.js to generate test fixtures — avoid hardcoded test data
228
+ - Extract test data to constants — never duplicate values across arrange/act/assert
229
+ - Use Vitest (never Jest)
230
+ - Mock HTTP with MSW (never mock fetch directly)
231
+ - Follow Arrange-Act-Assert pattern
232
+ - Tests must be deterministic — same result every run
233
+ - Reset handlers between tests for isolation
234
+ - Avoid conditional logic in tests unless absolutely necessary
235
+ - Ensure all code paths have corresponding tests
236
+ - Test happy paths, unhappy paths, and edge cases
237
+ - Never modify tests to pass without understanding root cause
238
+
239
+ ## Dependencies
240
+
241
+ - Use latest LTS Node.js — check with `nvm ls-remote --lts`, update `.nvmrc`
242
+ - Pin ALL dependencies to exact versions (no ^ or ~)
243
+ - Use explicit version numbers when adding new dependencies
244
+ - Search npm for latest stable version before adding
245
+ - Run `npm audit` after any dependency change
246
+ - Ensure `package-lock.json` is updated correctly
247
+ - Use Dependabot to keep dependencies current
248
+
249
+ ## GitHub Actions
250
+
251
+ - Validation must be automated via GitHub Actions and runnable locally the same way
252
+ - Validate all workflows using actionlint
253
+ - Validate all YAML files using yamllint
254
+ - Pin all 3rd party Actions to specific version or commit SHA
255
+ - Keep all 3rd party Actions updated to latest version
256
+
257
+ ## Boundaries
258
+
259
+ **✅ Always do:**
260
+ - Run `nvm use` before any npm command
261
+ - Write tests before implementation (TDD)
262
+ - Run lint and tests after every change
263
+ - Run full validation before commits
264
+ - Use existing patterns from codebase
265
+ - Work in small increments
266
+ - Use Context7 MCP tools for code generation and documentation
267
+
268
+ **⚠️ Ask first:**
269
+ - Adding new dependencies
270
+ - Changing project structure
271
+ - Modifying GitHub Actions workflows
272
+ - Database schema changes
273
+
274
+ **🚫 Never do:**
275
+ - Skip the TDD workflow
276
+ - Store secrets in code (use environment variables)
277
+ - Use Jest (use Vitest)
278
+ - Mock fetch directly (use MSW)
279
+ - Modify tests to pass without fixing root cause
280
+ - Add dependencies without explicit version numbers
281
+ - Use type assertions (`as Type`) on external/API data
@@ -0,0 +1,46 @@
1
+ ---
2
+ applyTo: ".github/workflows/*.{yml,yaml}"
3
+ ---
4
+
5
+ # Pipeline Instructions
6
+
7
+ ## MANDATORY: After Modifying Workflows
8
+
9
+ Run these validation commands in order:
10
+
11
+ ```bash
12
+ npm run lint:workflows # Validate GitHub Actions workflows with actionlint
13
+ npm run lint:yaml # Validate YAML syntax with yamllint
14
+ ```
15
+
16
+ ## Workflow Structure Requirements
17
+
18
+ 1. Every workflow MUST include test and lint jobs.
19
+ 2. Reference Node.js version from `.nvmrc` using `actions/setup-node` with `node-version-file` input.
20
+ 3. Use official setup actions: `actions/checkout`, `actions/setup-node`, `actions/cache`.
21
+
22
+ ## Action Pinning Format
23
+
24
+ Pin ALL third-party actions to exact commit SHA with version comment:
25
+
26
+ ```yaml
27
+ # CORRECT format:
28
+ uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
29
+
30
+ # INCORRECT formats (do NOT use):
31
+ uses: actions/checkout@v4 # ❌ version tag only
32
+ uses: actions/checkout@v4.1.1 # ❌ version tag only
33
+ uses: actions/checkout@main # ❌ branch reference
34
+ ```
35
+
36
+ Before adding any action:
37
+ 1. Check GitHub for the LATEST stable version
38
+ 2. Find the full commit SHA for that version
39
+ 3. Add both SHA and version comment
40
+
41
+ ## Runner Requirements
42
+
43
+ | Workflow | Runner |
44
+ |----------|--------|
45
+ | Default (all workflows) | `ubuntu-latest` |
46
+ | `copilot-setup-steps.yml` | May use different runners as needed |