@lousy-agents/cli 1.0.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.
- package/LICENSE +21 -0
- package/README.md +148 -0
- package/dist/commands/copilot-setup.d.ts +5 -0
- package/dist/commands/copilot-setup.d.ts.map +1 -0
- package/dist/commands/copilot-setup.js +97 -0
- package/dist/commands/copilot-setup.js.map +1 -0
- package/dist/commands/init.d.ts +12 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +115 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/new.d.ts +11 -0
- package/dist/commands/new.d.ts.map +1 -0
- package/dist/commands/new.js +41 -0
- package/dist/commands/new.js.map +1 -0
- package/dist/entities/copilot-agent.d.ts +15 -0
- package/dist/entities/copilot-agent.d.ts.map +1 -0
- package/dist/entities/copilot-agent.js +53 -0
- package/dist/entities/copilot-agent.js.map +1 -0
- package/dist/entities/copilot-setup.d.ts +65 -0
- package/dist/entities/copilot-setup.d.ts.map +1 -0
- package/dist/entities/copilot-setup.js +6 -0
- package/dist/entities/copilot-setup.js.map +1 -0
- package/dist/entities/index.d.ts +6 -0
- package/dist/entities/index.d.ts.map +1 -0
- package/dist/entities/index.js +6 -0
- package/dist/entities/index.js.map +1 -0
- package/dist/gateways/action-version-gateway.d.ts +39 -0
- package/dist/gateways/action-version-gateway.d.ts.map +1 -0
- package/dist/gateways/action-version-gateway.js +47 -0
- package/dist/gateways/action-version-gateway.js.map +1 -0
- package/dist/gateways/agent-file-gateway.d.ts +50 -0
- package/dist/gateways/agent-file-gateway.d.ts.map +1 -0
- package/dist/gateways/agent-file-gateway.js +34 -0
- package/dist/gateways/agent-file-gateway.js.map +1 -0
- package/dist/gateways/environment-gateway.d.ts +30 -0
- package/dist/gateways/environment-gateway.d.ts.map +1 -0
- package/dist/gateways/environment-gateway.js +56 -0
- package/dist/gateways/environment-gateway.js.map +1 -0
- package/dist/gateways/file-system-utils.d.ts +8 -0
- package/dist/gateways/file-system-utils.d.ts.map +1 -0
- package/dist/gateways/file-system-utils.js +17 -0
- package/dist/gateways/file-system-utils.js.map +1 -0
- package/dist/gateways/file-system-workflow-gateway.d.ts +27 -0
- package/dist/gateways/file-system-workflow-gateway.d.ts.map +1 -0
- package/dist/gateways/file-system-workflow-gateway.js +99 -0
- package/dist/gateways/file-system-workflow-gateway.js.map +1 -0
- package/dist/gateways/index.d.ts +9 -0
- package/dist/gateways/index.d.ts.map +1 -0
- package/dist/gateways/index.js +9 -0
- package/dist/gateways/index.js.map +1 -0
- package/dist/gateways/workflow-gateway.d.ts +43 -0
- package/dist/gateways/workflow-gateway.d.ts.map +1 -0
- package/dist/gateways/workflow-gateway.js +6 -0
- package/dist/gateways/workflow-gateway.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +27 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +226 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/copilot-setup-config.d.ts +79 -0
- package/dist/lib/copilot-setup-config.d.ts.map +1 -0
- package/dist/lib/copilot-setup-config.js +119 -0
- package/dist/lib/copilot-setup-config.js.map +1 -0
- package/dist/lib/filesystem-structure.d.ts +45 -0
- package/dist/lib/filesystem-structure.d.ts.map +1 -0
- package/dist/lib/filesystem-structure.js +69 -0
- package/dist/lib/filesystem-structure.js.map +1 -0
- package/dist/lib/mcp-test-client.d.ts +43 -0
- package/dist/lib/mcp-test-client.d.ts.map +1 -0
- package/dist/lib/mcp-test-client.js +167 -0
- package/dist/lib/mcp-test-client.js.map +1 -0
- package/dist/lib/project-name-validation.d.ts +43 -0
- package/dist/lib/project-name-validation.d.ts.map +1 -0
- package/dist/lib/project-name-validation.js +131 -0
- package/dist/lib/project-name-validation.js.map +1 -0
- package/dist/mcp/index.d.ts +5 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +5 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +15 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +120 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/analyze-action-versions.d.ts +9 -0
- package/dist/mcp/tools/analyze-action-versions.d.ts.map +1 -0
- package/dist/mcp/tools/analyze-action-versions.js +81 -0
- package/dist/mcp/tools/analyze-action-versions.js.map +1 -0
- package/dist/mcp/tools/create-copilot-setup-workflow.d.ts +9 -0
- package/dist/mcp/tools/create-copilot-setup-workflow.d.ts.map +1 -0
- package/dist/mcp/tools/create-copilot-setup-workflow.js +121 -0
- package/dist/mcp/tools/create-copilot-setup-workflow.js.map +1 -0
- package/dist/mcp/tools/discover-environment.d.ts +9 -0
- package/dist/mcp/tools/discover-environment.d.ts.map +1 -0
- package/dist/mcp/tools/discover-environment.js +30 -0
- package/dist/mcp/tools/discover-environment.js.map +1 -0
- package/dist/mcp/tools/discover-workflow-setup-actions.d.ts +9 -0
- package/dist/mcp/tools/discover-workflow-setup-actions.d.ts.map +1 -0
- package/dist/mcp/tools/discover-workflow-setup-actions.js +37 -0
- package/dist/mcp/tools/discover-workflow-setup-actions.js.map +1 -0
- package/dist/mcp/tools/index.d.ts +11 -0
- package/dist/mcp/tools/index.d.ts.map +1 -0
- package/dist/mcp/tools/index.js +11 -0
- package/dist/mcp/tools/index.js.map +1 -0
- package/dist/mcp/tools/read-copilot-setup-workflow.d.ts +9 -0
- package/dist/mcp/tools/read-copilot-setup-workflow.d.ts.map +1 -0
- package/dist/mcp/tools/read-copilot-setup-workflow.js +38 -0
- package/dist/mcp/tools/read-copilot-setup-workflow.js.map +1 -0
- package/dist/mcp/tools/resolve-action-versions.d.ts +10 -0
- package/dist/mcp/tools/resolve-action-versions.d.ts.map +1 -0
- package/dist/mcp/tools/resolve-action-versions.js +61 -0
- package/dist/mcp/tools/resolve-action-versions.js.map +1 -0
- package/dist/mcp/tools/types.d.ts +67 -0
- package/dist/mcp/tools/types.d.ts.map +1 -0
- package/dist/mcp/tools/types.js +24 -0
- package/dist/mcp/tools/types.js.map +1 -0
- package/dist/mcp-server.d.ts +7 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +17 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/use-cases/action-resolution.d.ts +66 -0
- package/dist/use-cases/action-resolution.d.ts.map +1 -0
- package/dist/use-cases/action-resolution.js +107 -0
- package/dist/use-cases/action-resolution.js.map +1 -0
- package/dist/use-cases/candidate-builder.d.ts +17 -0
- package/dist/use-cases/candidate-builder.d.ts.map +1 -0
- package/dist/use-cases/candidate-builder.js +67 -0
- package/dist/use-cases/candidate-builder.js.map +1 -0
- package/dist/use-cases/copilot-setup.d.ts +8 -0
- package/dist/use-cases/copilot-setup.d.ts.map +1 -0
- package/dist/use-cases/copilot-setup.js +10 -0
- package/dist/use-cases/copilot-setup.js.map +1 -0
- package/dist/use-cases/create-copilot-agent.d.ts +29 -0
- package/dist/use-cases/create-copilot-agent.d.ts.map +1 -0
- package/dist/use-cases/create-copilot-agent.js +73 -0
- package/dist/use-cases/create-copilot-agent.js.map +1 -0
- package/dist/use-cases/index.d.ts +9 -0
- package/dist/use-cases/index.d.ts.map +1 -0
- package/dist/use-cases/index.js +9 -0
- package/dist/use-cases/index.js.map +1 -0
- package/dist/use-cases/setup-step-discovery.d.ts +87 -0
- package/dist/use-cases/setup-step-discovery.d.ts.map +1 -0
- package/dist/use-cases/setup-step-discovery.js +202 -0
- package/dist/use-cases/setup-step-discovery.js.map +1 -0
- package/dist/use-cases/workflow-generator.d.ts +34 -0
- package/dist/use-cases/workflow-generator.d.ts.map +1 -0
- package/dist/use-cases/workflow-generator.js +195 -0
- package/dist/use-cases/workflow-generator.js.map +1 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Zach Pratt
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# Lousy Agents
|
|
2
|
+
|
|
3
|
+
**Turn "lousy" AI outputs into production-grade code.**
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
## TL;DR
|
|
8
|
+
|
|
9
|
+
A CLI tool that scaffolds projects with the structure AI coding assistants need to be effective. Run `npx @lousy-agents/cli init` to create a new project with testing, linting, and GitHub Copilot configuration. Run `npx @lousy-agents/cli copilot-setup` in existing projects to generate a workflow that gives Copilot your environment context.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
Lousy Agents is a CLI scaffolding tool that sets up your projects with the structure, instructions, and feedback loops that AI coding assistants need to be effective. One command gives you a production-ready development environment with testing, linting, and AI assistant configuration.
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Scaffold a new webapp project (no install required)
|
|
19
|
+
npx @lousy-agents/cli init --kind webapp
|
|
20
|
+
|
|
21
|
+
# Or use interactive mode to choose your project type
|
|
22
|
+
npx @lousy-agents/cli init
|
|
23
|
+
|
|
24
|
+
# Generate GitHub Copilot setup workflow from your project configuration
|
|
25
|
+
npx @lousy-agents/cli copilot-setup
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Table of Contents
|
|
29
|
+
|
|
30
|
+
- [Who This Is For](#who-this-is-for)
|
|
31
|
+
- [Why This Exists](#why-this-exists)
|
|
32
|
+
- [Features](#features)
|
|
33
|
+
- [Installation](#installation)
|
|
34
|
+
- [Usage](#usage)
|
|
35
|
+
- [Roadmap](#roadmap)
|
|
36
|
+
- [Documentation](#documentation)
|
|
37
|
+
- [Reference Example](#reference-example)
|
|
38
|
+
|
|
39
|
+
## Who This Is For
|
|
40
|
+
|
|
41
|
+
- **Software Engineers**: Frustrated by inconsistent AI output and looking for proven patterns to improve results.
|
|
42
|
+
- **Curious Beginners**: Interested in AI-assisted coding but unsure how to set things up for success.
|
|
43
|
+
- **Team Leads**: Exploring how to standardize AI tooling across a team or project.
|
|
44
|
+
- **Platform Engineers**: Need to automate project scaffolding in scripts or CI/CD pipelines.
|
|
45
|
+
|
|
46
|
+
No prior experience with coding agents is required—just curiosity and a willingness to experiment.
|
|
47
|
+
|
|
48
|
+
## Why This Exists
|
|
49
|
+
|
|
50
|
+
AI coding assistants work best when given clear constraints. Without structure, they guess—and often guess wrong. Lousy Agents provides the scaffolding they need to succeed:
|
|
51
|
+
|
|
52
|
+
- **Instructions & Specs**: Templates that clearly communicate your intent, so agents produce code that matches your vision.
|
|
53
|
+
- **Feedback Loops**: Pre-configured testing ([Vitest](https://vitest.dev/)) and linting ([Biome](https://biomejs.dev/)) that let agents catch and fix their own mistakes immediately.
|
|
54
|
+
- **Copilot Configuration**: Settings and workflows that ground AI assistants in your specific engineering standards.
|
|
55
|
+
|
|
56
|
+
## Features
|
|
57
|
+
|
|
58
|
+
### CLI Commands
|
|
59
|
+
|
|
60
|
+
- **[`init`](docs/init.md)** - Scaffold new projects with testing, linting, and Copilot configuration
|
|
61
|
+
- **[`new`](docs/new.md)** - Create new resources like custom GitHub Copilot agents
|
|
62
|
+
- **[`copilot-setup`](docs/copilot-setup.md)** - Generate GitHub Actions workflows for Copilot environment setup
|
|
63
|
+
|
|
64
|
+
### MCP Server
|
|
65
|
+
|
|
66
|
+
- **[MCP Server](docs/mcp-server.md)** - Model Context Protocol server for AI assistant integration
|
|
67
|
+
|
|
68
|
+
### Spec-Driven Development
|
|
69
|
+
|
|
70
|
+
A methodology where you write clear specifications *first*, giving agents precise requirements to implement—rather than vague prompts. Each scaffolded project includes instruction files for writing specs and tests.
|
|
71
|
+
|
|
72
|
+
### Non-Interactive Mode
|
|
73
|
+
|
|
74
|
+
Use the `--kind` flag to skip prompts and integrate into scripts or automation:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
npx @lousy-agents/cli init --kind webapp # No prompts, perfect for CI/CD
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Installation
|
|
81
|
+
|
|
82
|
+
No installation required! Use npx to run directly:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npx @lousy-agents/cli init
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
For frequent use, install globally:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npm install -g @lousy-agents/cli
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Usage
|
|
95
|
+
|
|
96
|
+
For detailed documentation on each command, see:
|
|
97
|
+
|
|
98
|
+
- **[`init` command](docs/init.md)** - Scaffold new projects
|
|
99
|
+
- **[`new` command](docs/new.md)** - Create new resources
|
|
100
|
+
- **[`copilot-setup` command](docs/copilot-setup.md)** - Generate Copilot workflows
|
|
101
|
+
- **[MCP Server](docs/mcp-server.md)** - AI assistant integration
|
|
102
|
+
|
|
103
|
+
### Quick Examples
|
|
104
|
+
|
|
105
|
+
**Create a new webapp:**
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
npx lousy-agents init --kind webapp
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Create a custom Copilot agent:**
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npx lousy-agents new --copilot-agent security
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Generate Copilot setup workflow:**
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
npx lousy-agents copilot-setup
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Roadmap
|
|
124
|
+
|
|
125
|
+
| Feature | Status |
|
|
126
|
+
|---------|--------|
|
|
127
|
+
| Scaffolding for webapps | In Progress |
|
|
128
|
+
| Scaffolding for CLI | Not Started |
|
|
129
|
+
| Scaffolding for REST APIs | Not Started |
|
|
130
|
+
| Scaffolding for GraphQL APIs | Not Started |
|
|
131
|
+
| MCP server package | ✅ Complete |
|
|
132
|
+
|
|
133
|
+
## Documentation
|
|
134
|
+
|
|
135
|
+
- **[`init` Command](docs/init.md)** - Project scaffolding
|
|
136
|
+
- **[`new` Command](docs/new.md)** - Create new resources
|
|
137
|
+
- **[`copilot-setup` Command](docs/copilot-setup.md)** - Workflow generation
|
|
138
|
+
- **[MCP Server](docs/mcp-server.md)** - AI assistant integration
|
|
139
|
+
|
|
140
|
+
## Reference Example
|
|
141
|
+
|
|
142
|
+
The [ui/copilot-with-react](ui/copilot-with-react) directory contains a fully working reference implementation demonstrating these patterns in action. It's a Next.js + TypeScript project with:
|
|
143
|
+
|
|
144
|
+
- Pre-configured testing (Vitest) and linting (Biome)
|
|
145
|
+
- GitHub Copilot instructions and specs
|
|
146
|
+
- Dev Container configuration for GitHub Codespaces
|
|
147
|
+
|
|
148
|
+
Launch a GitHub Codespace to instantly spin up this environment and experiment with spec-driven development.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-setup.d.ts","sourceRoot":"","sources":["../../src/commands/copilot-setup.ts"],"names":[],"mappings":"AAyBA;;GAEG;AACH,eAAO,MAAM,mBAAmB,gCAyI9B,CAAC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { mkdir } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { defineCommand } from "citty";
|
|
4
|
+
import { consola } from "consola";
|
|
5
|
+
import { createEnvironmentGateway, createWorkflowGateway, fileExists, } from "../gateways/index.js";
|
|
6
|
+
import { buildCandidatesFromEnvironment, generateWorkflowContent, updateWorkflowWithMissingSteps, } from "../use-cases/copilot-setup.js";
|
|
7
|
+
import { findMissingCandidates, getExistingActionsFromWorkflow, mergeCandidates, } from "../use-cases/setup-step-discovery.js";
|
|
8
|
+
const copilotSetupArgs = {};
|
|
9
|
+
/**
|
|
10
|
+
* Main command implementation for copilot-setup
|
|
11
|
+
*/
|
|
12
|
+
export const copilotSetupCommand = defineCommand({
|
|
13
|
+
meta: {
|
|
14
|
+
name: "copilot-setup",
|
|
15
|
+
description: "Generate or update the Copilot Setup Steps workflow based on detected environment configuration",
|
|
16
|
+
},
|
|
17
|
+
args: copilotSetupArgs,
|
|
18
|
+
run: async (context) => {
|
|
19
|
+
// Support dependency injection for testing via context.data
|
|
20
|
+
const targetDir = typeof context.data?.targetDir === "string"
|
|
21
|
+
? context.data.targetDir
|
|
22
|
+
: process.cwd();
|
|
23
|
+
// Create gateways
|
|
24
|
+
const environmentGateway = createEnvironmentGateway();
|
|
25
|
+
const workflowGateway = createWorkflowGateway();
|
|
26
|
+
consola.info("Detecting environment configuration...");
|
|
27
|
+
// Step 1: Detect environment configuration files
|
|
28
|
+
const environment = await environmentGateway.detectEnvironment(targetDir);
|
|
29
|
+
if (environment.hasMise) {
|
|
30
|
+
consola.success("Found mise.toml - will use mise-action");
|
|
31
|
+
}
|
|
32
|
+
if (environment.versionFiles.length > 0) {
|
|
33
|
+
const fileNames = environment.versionFiles
|
|
34
|
+
.map((f) => f.filename)
|
|
35
|
+
.join(", ");
|
|
36
|
+
consola.success(`Found version files: ${fileNames}`);
|
|
37
|
+
}
|
|
38
|
+
// Step 2: Parse existing workflows for setup actions
|
|
39
|
+
const workflowsDir = join(targetDir, ".github", "workflows");
|
|
40
|
+
const workflowsDirExists = await fileExists(workflowsDir);
|
|
41
|
+
const workflowCandidates = workflowsDirExists
|
|
42
|
+
? await workflowGateway.parseWorkflowsForSetupActions(targetDir)
|
|
43
|
+
: [];
|
|
44
|
+
if (workflowCandidates.length > 0) {
|
|
45
|
+
const actionNames = workflowCandidates
|
|
46
|
+
.map((c) => c.action)
|
|
47
|
+
.join(", ");
|
|
48
|
+
consola.success(`Found setup actions in existing workflows: ${actionNames}`);
|
|
49
|
+
}
|
|
50
|
+
// Step 3: Build candidates from environment
|
|
51
|
+
const envCandidates = await buildCandidatesFromEnvironment(environment);
|
|
52
|
+
// Step 4: Merge candidates (workflow takes precedence)
|
|
53
|
+
const allCandidates = mergeCandidates(workflowCandidates, envCandidates);
|
|
54
|
+
if (allCandidates.length === 0) {
|
|
55
|
+
consola.warn("No environment configuration or setup actions detected. Creating minimal workflow with checkout only.");
|
|
56
|
+
}
|
|
57
|
+
// Step 5: Check if copilot-setup-steps.yml already exists
|
|
58
|
+
const workflowExists = await workflowGateway.copilotSetupWorkflowExists(targetDir);
|
|
59
|
+
// Ensure workflows directory exists
|
|
60
|
+
if (!workflowsDirExists) {
|
|
61
|
+
await mkdir(workflowsDir, { recursive: true });
|
|
62
|
+
}
|
|
63
|
+
if (workflowExists) {
|
|
64
|
+
// Update existing workflow
|
|
65
|
+
consola.info("Found existing copilot-setup-steps.yml - checking for missing steps...");
|
|
66
|
+
const existingWorkflow = await workflowGateway.readCopilotSetupWorkflow(targetDir);
|
|
67
|
+
const existingActions = getExistingActionsFromWorkflow(existingWorkflow);
|
|
68
|
+
const missingCandidates = findMissingCandidates(allCandidates, existingActions);
|
|
69
|
+
if (missingCandidates.length === 0) {
|
|
70
|
+
consola.success("Copilot Setup Steps workflow already contains all detected setup steps. No changes needed.");
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const missingNames = missingCandidates
|
|
74
|
+
.map((c) => c.action)
|
|
75
|
+
.join(", ");
|
|
76
|
+
consola.info(`Adding missing setup steps: ${missingNames}`);
|
|
77
|
+
const updatedContent = await updateWorkflowWithMissingSteps(existingWorkflow, missingCandidates);
|
|
78
|
+
await workflowGateway.writeCopilotSetupWorkflow(targetDir, updatedContent);
|
|
79
|
+
consola.success(`Updated copilot-setup-steps.yml with ${missingCandidates.length} new step(s)`);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
// Create new workflow
|
|
83
|
+
consola.info("Creating new copilot-setup-steps.yml workflow...");
|
|
84
|
+
const content = await generateWorkflowContent(allCandidates);
|
|
85
|
+
await workflowGateway.writeCopilotSetupWorkflow(targetDir, content);
|
|
86
|
+
const stepCount = allCandidates.length + 1; // +1 for checkout
|
|
87
|
+
consola.success(`Created copilot-setup-steps.yml with ${stepCount} step(s)`);
|
|
88
|
+
if (allCandidates.length > 0) {
|
|
89
|
+
const actionNames = allCandidates
|
|
90
|
+
.map((c) => c.action)
|
|
91
|
+
.join(", ");
|
|
92
|
+
consola.info(`Included setup steps: ${actionNames}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
//# sourceMappingURL=copilot-setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-setup.js","sourceRoot":"","sources":["../../src/commands/copilot-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EACH,wBAAwB,EACxB,qBAAqB,EACrB,UAAU,GACb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACH,8BAA8B,EAC9B,uBAAuB,EACvB,8BAA8B,GACjC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACH,qBAAqB,EACrB,8BAA8B,EAC9B,eAAe,GAClB,MAAM,sCAAsC,CAAC;AAE9C,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAI5B;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,aAAa,CAAC;IAC7C,IAAI,EAAE;QACF,IAAI,EAAE,eAAe;QACrB,WAAW,EACP,iGAAiG;KACxG;IACD,IAAI,EAAE,gBAAgB;IACtB,GAAG,EAAE,KAAK,EAAE,OAAyC,EAAE,EAAE;QACrD,4DAA4D;QAC5D,MAAM,SAAS,GACX,OAAO,OAAO,CAAC,IAAI,EAAE,SAAS,KAAK,QAAQ;YACvC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS;YACxB,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QAExB,kBAAkB;QAClB,MAAM,kBAAkB,GAAG,wBAAwB,EAAE,CAAC;QACtD,MAAM,eAAe,GAAG,qBAAqB,EAAE,CAAC;QAEhD,OAAO,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;QAEvD,iDAAiD;QACjD,MAAM,WAAW,GACb,MAAM,kBAAkB,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAE1D,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;YACtB,OAAO,CAAC,OAAO,CAAC,wCAAwC,CAAC,CAAC;QAC9D,CAAC;QAED,IAAI,WAAW,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtC,MAAM,SAAS,GAAG,WAAW,CAAC,YAAY;iBACrC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;iBACtB,IAAI,CAAC,IAAI,CAAC,CAAC;YAChB,OAAO,CAAC,OAAO,CAAC,wBAAwB,SAAS,EAAE,CAAC,CAAC;QACzD,CAAC;QAED,qDAAqD;QACrD,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;QAC7D,MAAM,kBAAkB,GAAG,MAAM,UAAU,CAAC,YAAY,CAAC,CAAC;QAE1D,MAAM,kBAAkB,GAAG,kBAAkB;YACzC,CAAC,CAAC,MAAM,eAAe,CAAC,6BAA6B,CAAC,SAAS,CAAC;YAChE,CAAC,CAAC,EAAE,CAAC;QAET,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,WAAW,GAAG,kBAAkB;iBACjC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;iBACpB,IAAI,CAAC,IAAI,CAAC,CAAC;YAChB,OAAO,CAAC,OAAO,CACX,8CAA8C,WAAW,EAAE,CAC9D,CAAC;QACN,CAAC;QAED,4CAA4C;QAC5C,MAAM,aAAa,GAAG,MAAM,8BAA8B,CAAC,WAAW,CAAC,CAAC;QAExE,uDAAuD;QACvD,MAAM,aAAa,GAAG,eAAe,CACjC,kBAAkB,EAClB,aAAa,CAChB,CAAC;QAEF,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,IAAI,CACR,uGAAuG,CAC1G,CAAC;QACN,CAAC;QAED,0DAA0D;QAC1D,MAAM,cAAc,GAChB,MAAM,eAAe,CAAC,0BAA0B,CAAC,SAAS,CAAC,CAAC;QAEhE,oCAAoC;QACpC,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACtB,MAAM,KAAK,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,IAAI,cAAc,EAAE,CAAC;YACjB,2BAA2B;YAC3B,OAAO,CAAC,IAAI,CACR,wEAAwE,CAC3E,CAAC;YAEF,MAAM,gBAAgB,GAClB,MAAM,eAAe,CAAC,wBAAwB,CAAC,SAAS,CAAC,CAAC;YAC9D,MAAM,eAAe,GACjB,8BAA8B,CAAC,gBAAgB,CAAC,CAAC;YAErD,MAAM,iBAAiB,GAAG,qBAAqB,CAC3C,aAAa,EACb,eAAe,CAClB,CAAC;YAEF,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACjC,OAAO,CAAC,OAAO,CACX,4FAA4F,CAC/F,CAAC;gBACF,OAAO;YACX,CAAC;YAED,MAAM,YAAY,GAAG,iBAAiB;iBACjC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;iBACpB,IAAI,CAAC,IAAI,CAAC,CAAC;YAChB,OAAO,CAAC,IAAI,CAAC,+BAA+B,YAAY,EAAE,CAAC,CAAC;YAE5D,MAAM,cAAc,GAAG,MAAM,8BAA8B,CACvD,gBAAgB,EAChB,iBAAiB,CACpB,CAAC;YAEF,MAAM,eAAe,CAAC,yBAAyB,CAC3C,SAAS,EACT,cAAc,CACjB,CAAC;YAEF,OAAO,CAAC,OAAO,CACX,wCAAwC,iBAAiB,CAAC,MAAM,cAAc,CACjF,CAAC;QACN,CAAC;aAAM,CAAC;YACJ,sBAAsB;YACtB,OAAO,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;YAEjE,MAAM,OAAO,GAAG,MAAM,uBAAuB,CAAC,aAAa,CAAC,CAAC;YAC7D,MAAM,eAAe,CAAC,yBAAyB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAEpE,MAAM,SAAS,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,kBAAkB;YAC9D,OAAO,CAAC,OAAO,CACX,wCAAwC,SAAS,UAAU,CAC9D,CAAC;YAEF,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3B,MAAM,WAAW,GAAG,aAAa;qBAC5B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;qBACpB,IAAI,CAAC,IAAI,CAAC,CAAC;gBAChB,OAAO,CAAC,IAAI,CAAC,yBAAyB,WAAW,EAAE,CAAC,CAAC;YACzD,CAAC;QACL,CAAC;IACL,CAAC;CACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const PROJECT_TYPE_OPTIONS: ("CLI" | "webapp" | "REST API" | "GraphQL API")[];
|
|
2
|
+
export declare const initCommand: import("citty").CommandDef<{
|
|
3
|
+
kind: {
|
|
4
|
+
type: "string";
|
|
5
|
+
description: string;
|
|
6
|
+
};
|
|
7
|
+
name: {
|
|
8
|
+
type: "string";
|
|
9
|
+
description: string;
|
|
10
|
+
};
|
|
11
|
+
}>;
|
|
12
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,oBAAoB,mDAA4B,CAAC;AAmE9D,eAAO,MAAM,WAAW;;;;;;;;;EAoFtB,CAAC"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { defineCommand } from "citty";
|
|
2
|
+
import { consola } from "consola";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { getProjectStructure } from "../lib/config.js";
|
|
5
|
+
import { createFilesystemStructure, } from "../lib/filesystem-structure.js";
|
|
6
|
+
import { getProjectNameError, isValidProjectName, } from "../lib/project-name-validation.js";
|
|
7
|
+
const ProjectTypeSchema = z.enum(["CLI", "webapp", "REST API", "GraphQL API"]);
|
|
8
|
+
export const PROJECT_TYPE_OPTIONS = ProjectTypeSchema.options;
|
|
9
|
+
const initArgs = {
|
|
10
|
+
kind: {
|
|
11
|
+
type: "string",
|
|
12
|
+
description: `Project type: ${PROJECT_TYPE_OPTIONS.join(", ")}`,
|
|
13
|
+
},
|
|
14
|
+
name: {
|
|
15
|
+
type: "string",
|
|
16
|
+
description: "Project name (used in package.json and other config files)",
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
function formatErrorMessage(error) {
|
|
20
|
+
return error instanceof Error ? error.message : String(error);
|
|
21
|
+
}
|
|
22
|
+
async function createCliScaffolding(targetDir) {
|
|
23
|
+
try {
|
|
24
|
+
// Load the CLI structure from configuration
|
|
25
|
+
const cliStructure = await getProjectStructure("CLI");
|
|
26
|
+
if (!cliStructure) {
|
|
27
|
+
consola.warn("No CLI project structure defined in configuration");
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
await createFilesystemStructure(cliStructure, targetDir);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
consola.error(`Failed to create CLI scaffolding: ${formatErrorMessage(error)}`);
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async function createWebappScaffolding(targetDir, templateContext) {
|
|
38
|
+
try {
|
|
39
|
+
// Load the webapp structure from configuration
|
|
40
|
+
const webappStructure = await getProjectStructure("webapp");
|
|
41
|
+
if (!webappStructure) {
|
|
42
|
+
consola.warn("No webapp project structure defined in configuration");
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
await createFilesystemStructure(webappStructure, targetDir, templateContext);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
consola.error(`Failed to create webapp scaffolding: ${formatErrorMessage(error)}`);
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export const initCommand = defineCommand({
|
|
53
|
+
meta: {
|
|
54
|
+
name: "init",
|
|
55
|
+
description: "Initialize a new project with lousy agents scaffolding",
|
|
56
|
+
},
|
|
57
|
+
args: initArgs,
|
|
58
|
+
run: async (context) => {
|
|
59
|
+
// Support dependency injection for testing via context.data
|
|
60
|
+
// Runtime checks for type safety
|
|
61
|
+
const targetDir = typeof context.data?.targetDir === "string"
|
|
62
|
+
? context.data.targetDir
|
|
63
|
+
: process.cwd();
|
|
64
|
+
const promptFn = typeof context.data?.prompt === "function"
|
|
65
|
+
? context.data.prompt
|
|
66
|
+
: consola.prompt.bind(consola);
|
|
67
|
+
// Use CLI argument if provided, otherwise prompt
|
|
68
|
+
const rawProjectType = context.args.kind
|
|
69
|
+
? context.args.kind
|
|
70
|
+
: await promptFn("What type of project are you initializing?", {
|
|
71
|
+
type: "select",
|
|
72
|
+
options: PROJECT_TYPE_OPTIONS,
|
|
73
|
+
});
|
|
74
|
+
// Validate the user input at runtime
|
|
75
|
+
const parseResult = ProjectTypeSchema.safeParse(rawProjectType);
|
|
76
|
+
if (!parseResult.success) {
|
|
77
|
+
const validOptions = PROJECT_TYPE_OPTIONS.join(", ");
|
|
78
|
+
consola.error(`Invalid project type selected: ${String(rawProjectType)}. Valid options are: ${validOptions}`);
|
|
79
|
+
throw new Error(`Invalid project type. Expected one of: ${validOptions}`);
|
|
80
|
+
}
|
|
81
|
+
const projectType = parseResult.data;
|
|
82
|
+
consola.success(`Selected project type: ${projectType}`);
|
|
83
|
+
if (projectType === "CLI") {
|
|
84
|
+
await createCliScaffolding(targetDir);
|
|
85
|
+
consola.info("CLI project scaffolding complete. Check the .github directory for instructions.");
|
|
86
|
+
}
|
|
87
|
+
else if (projectType === "webapp") {
|
|
88
|
+
// Get project name from CLI argument or prompt
|
|
89
|
+
const rawProjectName = context.args.name
|
|
90
|
+
? context.args.name
|
|
91
|
+
: await promptFn("What is your project name?", {
|
|
92
|
+
type: "text",
|
|
93
|
+
placeholder: "my-webapp",
|
|
94
|
+
});
|
|
95
|
+
const projectName = typeof rawProjectName === "string" ? rawProjectName.trim() : "";
|
|
96
|
+
if (!projectName) {
|
|
97
|
+
consola.error("Project name is required for webapp projects");
|
|
98
|
+
throw new Error("Project name is required");
|
|
99
|
+
}
|
|
100
|
+
if (!isValidProjectName(projectName)) {
|
|
101
|
+
const errorMessage = getProjectNameError(projectName) ||
|
|
102
|
+
"Invalid npm package name";
|
|
103
|
+
consola.error(`Invalid project name: "${projectName}". ${errorMessage}`);
|
|
104
|
+
throw new Error(`Invalid project name. ${errorMessage}`);
|
|
105
|
+
}
|
|
106
|
+
const templateContext = { projectName };
|
|
107
|
+
await createWebappScaffolding(targetDir, templateContext);
|
|
108
|
+
consola.info("Webapp project scaffolding complete. Run 'npm install' to install dependencies.");
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
consola.info(`Scaffolding for ${projectType} projects will be implemented in a future release.`);
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `new` command for scaffolding new resources.
|
|
3
|
+
* Currently supports creating Copilot custom agents.
|
|
4
|
+
*/
|
|
5
|
+
export declare const newCommand: import("citty").CommandDef<{
|
|
6
|
+
"copilot-agent": {
|
|
7
|
+
type: "string";
|
|
8
|
+
description: string;
|
|
9
|
+
};
|
|
10
|
+
}>;
|
|
11
|
+
//# sourceMappingURL=new.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"new.d.ts","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"AAgBA;;;GAGG;AACH,eAAO,MAAM,UAAU;;;;;EAkCrB,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { defineCommand } from "citty";
|
|
2
|
+
import { consola } from "consola";
|
|
3
|
+
import { createAgentFileGateway } from "../gateways/agent-file-gateway.js";
|
|
4
|
+
import { CreateCopilotAgentUseCase } from "../use-cases/create-copilot-agent.js";
|
|
5
|
+
const newArgs = {
|
|
6
|
+
"copilot-agent": {
|
|
7
|
+
type: "string",
|
|
8
|
+
description: "Create a new GitHub Copilot custom agent with the specified name. Example: lousy-agents new --copilot-agent security",
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* The `new` command for scaffolding new resources.
|
|
13
|
+
* Currently supports creating Copilot custom agents.
|
|
14
|
+
*/
|
|
15
|
+
export const newCommand = defineCommand({
|
|
16
|
+
meta: {
|
|
17
|
+
name: "new",
|
|
18
|
+
description: "Create new resources (e.g., Copilot agents)",
|
|
19
|
+
},
|
|
20
|
+
args: newArgs,
|
|
21
|
+
run: async (context) => {
|
|
22
|
+
// Support dependency injection for testing via context.data
|
|
23
|
+
const targetDir = typeof context.data?.targetDir === "string"
|
|
24
|
+
? context.data.targetDir
|
|
25
|
+
: process.cwd();
|
|
26
|
+
const copilotAgentName = context.args["copilot-agent"];
|
|
27
|
+
if (!copilotAgentName) {
|
|
28
|
+
throw new Error("Missing required option: --copilot-agent <name>. Example: lousy-agents new --copilot-agent security");
|
|
29
|
+
}
|
|
30
|
+
// Create the use case with the file system gateway
|
|
31
|
+
const gateway = createAgentFileGateway();
|
|
32
|
+
const useCase = new CreateCopilotAgentUseCase(gateway);
|
|
33
|
+
// Execute the use case
|
|
34
|
+
const result = await useCase.execute(targetDir, copilotAgentName);
|
|
35
|
+
if (!result.success) {
|
|
36
|
+
throw new Error(result.error);
|
|
37
|
+
}
|
|
38
|
+
consola.success(`Created Copilot agent: ${result.filePath}`);
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
//# sourceMappingURL=new.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"new.js","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAEjF,MAAM,OAAO,GAAG;IACZ,eAAe,EAAE;QACb,IAAI,EAAE,QAAiB;QACvB,WAAW,EACP,sHAAsH;KAC7H;CACJ,CAAC;AAIF;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,aAAa,CAAC;IACpC,IAAI,EAAE;QACF,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,6CAA6C;KAC7D;IACD,IAAI,EAAE,OAAO;IACb,GAAG,EAAE,KAAK,EAAE,OAAgC,EAAE,EAAE;QAC5C,4DAA4D;QAC5D,MAAM,SAAS,GACX,OAAO,OAAO,CAAC,IAAI,EAAE,SAAS,KAAK,QAAQ;YACvC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS;YACxB,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QAExB,MAAM,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAEvD,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CACX,qGAAqG,CACxG,CAAC;QACN,CAAC;QAED,mDAAmD;QACnD,MAAM,OAAO,GAAG,sBAAsB,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,yBAAyB,CAAC,OAAO,CAAC,CAAC;QAEvD,uBAAuB;QACvB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;QAElE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;QAED,OAAO,CAAC,OAAO,CAAC,0BAA0B,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IACjE,CAAC;CACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core domain entity for GitHub Copilot custom agent files.
|
|
3
|
+
* Handles name normalization and content generation.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Normalizes an agent name to lowercase with hyphens.
|
|
7
|
+
* Handles spaces, mixed case, multiple spaces, and leading/trailing spaces.
|
|
8
|
+
*/
|
|
9
|
+
export declare function normalizeAgentName(name: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Generates the markdown content for a custom Copilot agent file.
|
|
12
|
+
* Includes YAML frontmatter, documentation link, and example structure.
|
|
13
|
+
*/
|
|
14
|
+
export declare function generateAgentContent(agentName: string): string;
|
|
15
|
+
//# sourceMappingURL=copilot-agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-agent.d.ts","sourceRoot":"","sources":["../../src/entities/copilot-agent.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAqC9D"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core domain entity for GitHub Copilot custom agent files.
|
|
3
|
+
* Handles name normalization and content generation.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Normalizes an agent name to lowercase with hyphens.
|
|
7
|
+
* Handles spaces, mixed case, multiple spaces, and leading/trailing spaces.
|
|
8
|
+
*/
|
|
9
|
+
export function normalizeAgentName(name) {
|
|
10
|
+
return name.trim().toLowerCase().replace(/\s+/g, "-");
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Generates the markdown content for a custom Copilot agent file.
|
|
14
|
+
* Includes YAML frontmatter, documentation link, and example structure.
|
|
15
|
+
*/
|
|
16
|
+
export function generateAgentContent(agentName) {
|
|
17
|
+
const normalizedName = normalizeAgentName(agentName);
|
|
18
|
+
return `---
|
|
19
|
+
name: ${normalizedName}
|
|
20
|
+
description: Brief description of what this agent does
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
<!--
|
|
24
|
+
This is a custom GitHub Copilot agent for repository-level use.
|
|
25
|
+
Learn more: https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/create-custom-agents
|
|
26
|
+
-->
|
|
27
|
+
|
|
28
|
+
# ${normalizedName} Agent
|
|
29
|
+
|
|
30
|
+
You are a ${normalizedName} agent specialized in {domain/responsibility}.
|
|
31
|
+
|
|
32
|
+
## Your Role
|
|
33
|
+
|
|
34
|
+
{Brief description of the agent's expertise and focus area}
|
|
35
|
+
|
|
36
|
+
## Responsibilities
|
|
37
|
+
|
|
38
|
+
- {Primary responsibility}
|
|
39
|
+
- {Secondary responsibility}
|
|
40
|
+
- {Additional responsibility}
|
|
41
|
+
|
|
42
|
+
## Guidelines
|
|
43
|
+
|
|
44
|
+
- {Guideline or best practice}
|
|
45
|
+
- {Guideline or best practice}
|
|
46
|
+
- {Guideline or best practice}
|
|
47
|
+
|
|
48
|
+
## Example Interactions
|
|
49
|
+
|
|
50
|
+
{Example of how the agent should respond to typical requests}
|
|
51
|
+
`;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=copilot-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-agent.js","sourceRoot":"","sources":["../../src/entities/copilot-agent.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC3C,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAAiB;IAClD,MAAM,cAAc,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAErD,OAAO;QACH,cAAc;;;;;;;;;IASlB,cAAc;;YAEN,cAAc;;;;;;;;;;;;;;;;;;;;;CAqBzB,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core domain entities for the Copilot Setup Steps feature.
|
|
3
|
+
* These are the fundamental types that represent the business domain.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Types of version files supported for detection
|
|
7
|
+
*/
|
|
8
|
+
export type VersionFileType = "node" | "python" | "java" | "ruby" | "go";
|
|
9
|
+
/**
|
|
10
|
+
* Represents a detected version file in the repository
|
|
11
|
+
*/
|
|
12
|
+
export interface VersionFile {
|
|
13
|
+
type: VersionFileType;
|
|
14
|
+
filename: string;
|
|
15
|
+
version?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Result of detecting environment configuration
|
|
19
|
+
*/
|
|
20
|
+
export interface DetectedEnvironment {
|
|
21
|
+
hasMise: boolean;
|
|
22
|
+
versionFiles: VersionFile[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Represents a setup step candidate extracted from workflows or version files
|
|
26
|
+
*/
|
|
27
|
+
export interface SetupStepCandidate {
|
|
28
|
+
action: string;
|
|
29
|
+
version?: string;
|
|
30
|
+
config?: Record<string, unknown>;
|
|
31
|
+
source: "version-file" | "workflow";
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Represents a step in a GitHub Actions workflow
|
|
35
|
+
*/
|
|
36
|
+
export interface WorkflowStep {
|
|
37
|
+
name?: string;
|
|
38
|
+
uses: string;
|
|
39
|
+
with?: Record<string, unknown>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Represents an action that needs version resolution.
|
|
43
|
+
* Used to prompt the LLM to look up the latest version.
|
|
44
|
+
*/
|
|
45
|
+
export interface ActionToResolve {
|
|
46
|
+
/** Action name without version (e.g., "actions/setup-node") */
|
|
47
|
+
action: string;
|
|
48
|
+
/** Placeholder used in workflow template (e.g., "RESOLVE_VERSION") */
|
|
49
|
+
currentPlaceholder: string;
|
|
50
|
+
/** URL to lookup latest version (e.g., "https://github.com/actions/setup-node/releases/latest") */
|
|
51
|
+
lookupUrl: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Represents a resolved action version with SHA and tag.
|
|
55
|
+
* Used when the LLM has looked up and resolved the version.
|
|
56
|
+
*/
|
|
57
|
+
export interface ResolvedVersion {
|
|
58
|
+
/** Action name without version (e.g., "actions/setup-node") */
|
|
59
|
+
action: string;
|
|
60
|
+
/** Resolved commit SHA */
|
|
61
|
+
sha: string;
|
|
62
|
+
/** Version tag for human-readable comment (e.g., "v4.0.0") */
|
|
63
|
+
versionTag: string;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=copilot-setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-setup.d.ts","sourceRoot":"","sources":["../../src/entities/copilot-setup.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,WAAW,EAAE,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,MAAM,EAAE,cAAc,GAAG,UAAU,CAAC;CACvC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC5B,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mGAAmG;IACnG,SAAS,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC5B,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAC;CACtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-setup.js","sourceRoot":"","sources":["../../src/entities/copilot-setup.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|