@lousy-agents/cli 2.2.1 → 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.
- package/api/copilot-with-fastify/biome.json +1 -1
- package/cli/copilot-with-citty/.devcontainer/devcontainer.json +76 -0
- package/cli/copilot-with-citty/.editorconfig +16 -0
- package/cli/copilot-with-citty/.github/ISSUE_TEMPLATE/feature-to-spec.yml +54 -0
- package/cli/copilot-with-citty/.github/copilot-instructions.md +228 -0
- package/cli/copilot-with-citty/.github/instructions/pipeline.instructions.md +92 -0
- package/cli/copilot-with-citty/.github/instructions/software-architecture.instructions.md +166 -0
- package/cli/copilot-with-citty/.github/instructions/spec.instructions.md +127 -0
- package/cli/copilot-with-citty/.github/instructions/test.instructions.md +157 -0
- package/cli/copilot-with-citty/.github/specs/README.md +84 -0
- package/cli/copilot-with-citty/.github/workflows/assign-copilot.yml +59 -0
- package/cli/copilot-with-citty/.github/workflows/ci.yml +67 -0
- package/cli/copilot-with-citty/.nvmrc +1 -0
- package/cli/copilot-with-citty/.vscode/extensions.json +13 -0
- package/cli/copilot-with-citty/.vscode/launch.json +25 -0
- package/cli/copilot-with-citty/.vscode/mcp.json +19 -0
- package/cli/copilot-with-citty/.yamllint +18 -0
- package/cli/copilot-with-citty/biome.json +31 -0
- package/cli/copilot-with-citty/package.json +29 -0
- package/cli/copilot-with-citty/tsconfig.json +28 -0
- package/cli/copilot-with-citty/vitest.config.ts +15 -0
- package/cli/copilot-with-citty/vitest.setup.ts +2 -0
- package/dist/index.js +205 -55
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.js +3 -0
- package/dist/mcp-server.js.map +1 -1
- package/package.json +3 -2
- package/ui/copilot-with-react/biome.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15244,6 +15244,7 @@ Example resolved format: actions/setup-node@1a2b3c4d5e6f # v4.0.0`;
|
|
|
15244
15244
|
const workflow = new Workflow("copilot-setup-steps.yml", {
|
|
15245
15245
|
name: "Copilot Setup Steps",
|
|
15246
15246
|
on: {
|
|
15247
|
+
// biome-ignore lint/style/useNamingConvention: GitHub Actions YAML schema requires snake_case
|
|
15247
15248
|
workflow_dispatch: {},
|
|
15248
15249
|
push: {
|
|
15249
15250
|
branches: [
|
|
@@ -15253,6 +15254,7 @@ Example resolved format: actions/setup-node@1a2b3c4d5e6f # v4.0.0`;
|
|
|
15253
15254
|
".github/workflows/copilot-setup-steps.yml"
|
|
15254
15255
|
]
|
|
15255
15256
|
},
|
|
15257
|
+
// biome-ignore lint/style/useNamingConvention: GitHub Actions YAML schema requires snake_case
|
|
15256
15258
|
pull_request: {
|
|
15257
15259
|
branches: [
|
|
15258
15260
|
"main"
|
|
@@ -29130,21 +29132,168 @@ const config_dirname = (0,external_node_path_.dirname)(config_filename);
|
|
|
29130
29132
|
const PROJECT_ROOT = (0,external_node_path_.join)(config_dirname, "..", "..");
|
|
29131
29133
|
const WEBAPP_TEMPLATE_DIR = (0,external_node_path_.join)(PROJECT_ROOT, "ui", "copilot-with-react");
|
|
29132
29134
|
const RESTAPI_TEMPLATE_DIR = (0,external_node_path_.join)(PROJECT_ROOT, "api", "copilot-with-fastify");
|
|
29135
|
+
const CLI_TEMPLATE_DIR = (0,external_node_path_.join)(PROJECT_ROOT, "cli", "copilot-with-citty");
|
|
29133
29136
|
/**
|
|
29134
|
-
*
|
|
29135
|
-
*/
|
|
29136
|
-
|
|
29137
|
-
|
|
29138
|
-
|
|
29139
|
-
|
|
29140
|
-
|
|
29141
|
-
|
|
29142
|
-
|
|
29143
|
-
|
|
29144
|
-
|
|
29145
|
-
|
|
29146
|
-
|
|
29147
|
-
}
|
|
29137
|
+
* Helper function to read CLI template files
|
|
29138
|
+
*/ function readCliTemplateFile(relativePath) {
|
|
29139
|
+
return readTemplateFile(relativePath, CLI_TEMPLATE_DIR);
|
|
29140
|
+
}
|
|
29141
|
+
/**
|
|
29142
|
+
* Cached CLI structure - lazy-loaded on first access
|
|
29143
|
+
*/ let cachedCliStructure = null;
|
|
29144
|
+
/**
|
|
29145
|
+
* Builds the CLI project filesystem structure by reading template files
|
|
29146
|
+
* This is called lazily only when CLI scaffolding is needed
|
|
29147
|
+
*/ function buildCliStructure() {
|
|
29148
|
+
if (cachedCliStructure) {
|
|
29149
|
+
return cachedCliStructure;
|
|
29150
|
+
}
|
|
29151
|
+
cachedCliStructure = {
|
|
29152
|
+
nodes: [
|
|
29153
|
+
// Root configuration files
|
|
29154
|
+
{
|
|
29155
|
+
type: "file",
|
|
29156
|
+
path: "package.json",
|
|
29157
|
+
content: readCliTemplateFile("package.json")
|
|
29158
|
+
},
|
|
29159
|
+
{
|
|
29160
|
+
type: "file",
|
|
29161
|
+
path: "tsconfig.json",
|
|
29162
|
+
content: readCliTemplateFile("tsconfig.json")
|
|
29163
|
+
},
|
|
29164
|
+
{
|
|
29165
|
+
type: "file",
|
|
29166
|
+
path: "vitest.config.ts",
|
|
29167
|
+
content: readCliTemplateFile("vitest.config.ts")
|
|
29168
|
+
},
|
|
29169
|
+
{
|
|
29170
|
+
type: "file",
|
|
29171
|
+
path: "vitest.setup.ts",
|
|
29172
|
+
content: readCliTemplateFile("vitest.setup.ts")
|
|
29173
|
+
},
|
|
29174
|
+
{
|
|
29175
|
+
type: "file",
|
|
29176
|
+
path: "biome.json",
|
|
29177
|
+
content: readCliTemplateFile("biome.json")
|
|
29178
|
+
},
|
|
29179
|
+
{
|
|
29180
|
+
type: "file",
|
|
29181
|
+
path: ".editorconfig",
|
|
29182
|
+
content: readCliTemplateFile(".editorconfig")
|
|
29183
|
+
},
|
|
29184
|
+
{
|
|
29185
|
+
type: "file",
|
|
29186
|
+
path: ".nvmrc",
|
|
29187
|
+
content: readCliTemplateFile(".nvmrc")
|
|
29188
|
+
},
|
|
29189
|
+
{
|
|
29190
|
+
type: "file",
|
|
29191
|
+
path: ".yamllint",
|
|
29192
|
+
content: readCliTemplateFile(".yamllint")
|
|
29193
|
+
},
|
|
29194
|
+
// GitHub copilot instructions
|
|
29195
|
+
{
|
|
29196
|
+
type: "directory",
|
|
29197
|
+
path: ".github"
|
|
29198
|
+
},
|
|
29199
|
+
{
|
|
29200
|
+
type: "directory",
|
|
29201
|
+
path: ".github/instructions"
|
|
29202
|
+
},
|
|
29203
|
+
{
|
|
29204
|
+
type: "file",
|
|
29205
|
+
path: ".github/copilot-instructions.md",
|
|
29206
|
+
content: readCliTemplateFile(".github/copilot-instructions.md")
|
|
29207
|
+
},
|
|
29208
|
+
{
|
|
29209
|
+
type: "file",
|
|
29210
|
+
path: ".github/instructions/test.instructions.md",
|
|
29211
|
+
content: readCliTemplateFile(".github/instructions/test.instructions.md")
|
|
29212
|
+
},
|
|
29213
|
+
{
|
|
29214
|
+
type: "file",
|
|
29215
|
+
path: ".github/instructions/spec.instructions.md",
|
|
29216
|
+
content: readCliTemplateFile(".github/instructions/spec.instructions.md")
|
|
29217
|
+
},
|
|
29218
|
+
{
|
|
29219
|
+
type: "file",
|
|
29220
|
+
path: ".github/instructions/pipeline.instructions.md",
|
|
29221
|
+
content: readCliTemplateFile(".github/instructions/pipeline.instructions.md")
|
|
29222
|
+
},
|
|
29223
|
+
{
|
|
29224
|
+
type: "file",
|
|
29225
|
+
path: ".github/instructions/software-architecture.instructions.md",
|
|
29226
|
+
content: readCliTemplateFile(".github/instructions/software-architecture.instructions.md")
|
|
29227
|
+
},
|
|
29228
|
+
// GitHub Issue Templates
|
|
29229
|
+
{
|
|
29230
|
+
type: "directory",
|
|
29231
|
+
path: ".github/ISSUE_TEMPLATE"
|
|
29232
|
+
},
|
|
29233
|
+
{
|
|
29234
|
+
type: "file",
|
|
29235
|
+
path: ".github/ISSUE_TEMPLATE/feature-to-spec.yml",
|
|
29236
|
+
content: readCliTemplateFile(".github/ISSUE_TEMPLATE/feature-to-spec.yml")
|
|
29237
|
+
},
|
|
29238
|
+
// GitHub Workflows
|
|
29239
|
+
{
|
|
29240
|
+
type: "directory",
|
|
29241
|
+
path: ".github/workflows"
|
|
29242
|
+
},
|
|
29243
|
+
{
|
|
29244
|
+
type: "file",
|
|
29245
|
+
path: ".github/workflows/assign-copilot.yml",
|
|
29246
|
+
content: readCliTemplateFile(".github/workflows/assign-copilot.yml")
|
|
29247
|
+
},
|
|
29248
|
+
{
|
|
29249
|
+
type: "file",
|
|
29250
|
+
path: ".github/workflows/ci.yml",
|
|
29251
|
+
content: readCliTemplateFile(".github/workflows/ci.yml")
|
|
29252
|
+
},
|
|
29253
|
+
// Specs directory
|
|
29254
|
+
{
|
|
29255
|
+
type: "directory",
|
|
29256
|
+
path: ".github/specs"
|
|
29257
|
+
},
|
|
29258
|
+
{
|
|
29259
|
+
type: "file",
|
|
29260
|
+
path: ".github/specs/README.md",
|
|
29261
|
+
content: readCliTemplateFile(".github/specs/README.md")
|
|
29262
|
+
},
|
|
29263
|
+
// VSCode configuration
|
|
29264
|
+
{
|
|
29265
|
+
type: "directory",
|
|
29266
|
+
path: ".vscode"
|
|
29267
|
+
},
|
|
29268
|
+
{
|
|
29269
|
+
type: "file",
|
|
29270
|
+
path: ".vscode/extensions.json",
|
|
29271
|
+
content: readCliTemplateFile(".vscode/extensions.json")
|
|
29272
|
+
},
|
|
29273
|
+
{
|
|
29274
|
+
type: "file",
|
|
29275
|
+
path: ".vscode/launch.json",
|
|
29276
|
+
content: readCliTemplateFile(".vscode/launch.json")
|
|
29277
|
+
},
|
|
29278
|
+
{
|
|
29279
|
+
type: "file",
|
|
29280
|
+
path: ".vscode/mcp.json",
|
|
29281
|
+
content: readCliTemplateFile(".vscode/mcp.json")
|
|
29282
|
+
},
|
|
29283
|
+
// Devcontainer configuration
|
|
29284
|
+
{
|
|
29285
|
+
type: "directory",
|
|
29286
|
+
path: ".devcontainer"
|
|
29287
|
+
},
|
|
29288
|
+
{
|
|
29289
|
+
type: "file",
|
|
29290
|
+
path: ".devcontainer/devcontainer.json",
|
|
29291
|
+
content: readCliTemplateFile(".devcontainer/devcontainer.json")
|
|
29292
|
+
}
|
|
29293
|
+
]
|
|
29294
|
+
};
|
|
29295
|
+
return cachedCliStructure;
|
|
29296
|
+
}
|
|
29148
29297
|
/**
|
|
29149
29298
|
* Helper function to read template file content
|
|
29150
29299
|
* @throws Error if template file cannot be read
|
|
@@ -29478,20 +29627,16 @@ const RESTAPI_TEMPLATE_DIR = (0,external_node_path_.join)(PROJECT_ROOT, "api", "
|
|
|
29478
29627
|
/**
|
|
29479
29628
|
* Loads the configuration for the init command
|
|
29480
29629
|
* Falls back to defaults if no configuration is found
|
|
29481
|
-
* Note:
|
|
29630
|
+
* Note: project structures are lazy-loaded only when requested
|
|
29482
29631
|
*/ async function loadInitConfig() {
|
|
29483
29632
|
const { config } = await loadConfig({
|
|
29484
29633
|
name: "lousy-agents",
|
|
29485
29634
|
defaults: {
|
|
29486
|
-
structures: {
|
|
29487
|
-
cli: DEFAULT_CLI_STRUCTURE
|
|
29488
|
-
}
|
|
29635
|
+
structures: {}
|
|
29489
29636
|
}
|
|
29490
29637
|
});
|
|
29491
29638
|
return config || {
|
|
29492
|
-
structures: {
|
|
29493
|
-
cli: DEFAULT_CLI_STRUCTURE
|
|
29494
|
-
}
|
|
29639
|
+
structures: {}
|
|
29495
29640
|
};
|
|
29496
29641
|
}
|
|
29497
29642
|
/**
|
|
@@ -29508,9 +29653,9 @@ const RESTAPI_TEMPLATE_DIR = (0,external_node_path_.join)(PROJECT_ROOT, "api", "
|
|
|
29508
29653
|
if (projectType === "api") {
|
|
29509
29654
|
return config.structures?.api || buildRestApiStructure();
|
|
29510
29655
|
}
|
|
29511
|
-
// CLI
|
|
29656
|
+
// Lazy-load CLI structure only when requested
|
|
29512
29657
|
if (projectType === "cli") {
|
|
29513
|
-
return config.structures?.cli ||
|
|
29658
|
+
return config.structures?.cli || buildCliStructure();
|
|
29514
29659
|
}
|
|
29515
29660
|
// GraphQL is not yet implemented
|
|
29516
29661
|
throw new Error(`Project type "${projectType}" is not yet supported. Supported types: cli, webapp, api`);
|
|
@@ -30228,8 +30373,26 @@ const ProjectTypeSchema = schemas_enum([
|
|
|
30228
30373
|
const PROJECT_TYPE_OPTIONS = ProjectTypeSchema.options;
|
|
30229
30374
|
const SUPPORTED_PROJECT_TYPES = [
|
|
30230
30375
|
"webapp",
|
|
30231
|
-
"api"
|
|
30376
|
+
"api",
|
|
30377
|
+
"cli"
|
|
30232
30378
|
];
|
|
30379
|
+
const PROJECT_TYPE_CONFIGS = {
|
|
30380
|
+
cli: {
|
|
30381
|
+
label: "CLI",
|
|
30382
|
+
placeholder: "my-cli",
|
|
30383
|
+
structureKey: "cli"
|
|
30384
|
+
},
|
|
30385
|
+
webapp: {
|
|
30386
|
+
label: "webapp",
|
|
30387
|
+
placeholder: "my-webapp",
|
|
30388
|
+
structureKey: "webapp"
|
|
30389
|
+
},
|
|
30390
|
+
api: {
|
|
30391
|
+
label: "REST API",
|
|
30392
|
+
placeholder: "my-rest-api",
|
|
30393
|
+
structureKey: "api"
|
|
30394
|
+
}
|
|
30395
|
+
};
|
|
30233
30396
|
const initArgs = {
|
|
30234
30397
|
kind: {
|
|
30235
30398
|
type: "string",
|
|
@@ -30262,23 +30425,18 @@ async function getValidatedProjectName(promptFn, existingName, projectTypeLabel,
|
|
|
30262
30425
|
projectName
|
|
30263
30426
|
};
|
|
30264
30427
|
}
|
|
30265
|
-
async function
|
|
30428
|
+
async function scaffoldProject(projectType, targetDir, templateContext) {
|
|
30429
|
+
const config = PROJECT_TYPE_CONFIGS[projectType];
|
|
30266
30430
|
try {
|
|
30267
|
-
const
|
|
30268
|
-
await createFilesystemStructure(
|
|
30431
|
+
const structure = await getProjectStructure(config.structureKey);
|
|
30432
|
+
await createFilesystemStructure(structure, targetDir, templateContext);
|
|
30269
30433
|
} catch (error) {
|
|
30270
|
-
consola.error(`Failed to create
|
|
30434
|
+
consola.error(`Failed to create ${config.label} scaffolding: ${formatErrorMessage(error)}`);
|
|
30271
30435
|
throw error;
|
|
30272
30436
|
}
|
|
30273
30437
|
}
|
|
30274
|
-
|
|
30275
|
-
|
|
30276
|
-
const restApiStructure = await getProjectStructure("api");
|
|
30277
|
-
await createFilesystemStructure(restApiStructure, targetDir, templateContext);
|
|
30278
|
-
} catch (error) {
|
|
30279
|
-
consola.error(`Failed to create REST API scaffolding: ${formatErrorMessage(error)}`);
|
|
30280
|
-
throw error;
|
|
30281
|
-
}
|
|
30438
|
+
function isSupportedProjectType(projectType) {
|
|
30439
|
+
return SUPPORTED_PROJECT_TYPES.includes(projectType);
|
|
30282
30440
|
}
|
|
30283
30441
|
const initCommand = defineCommand({
|
|
30284
30442
|
meta: {
|
|
@@ -30301,25 +30459,17 @@ const initCommand = defineCommand({
|
|
|
30301
30459
|
}
|
|
30302
30460
|
const projectType = parseResult.data;
|
|
30303
30461
|
consola.success(`Selected project type: ${projectType}`);
|
|
30304
|
-
if (projectType
|
|
30305
|
-
|
|
30306
|
-
|
|
30307
|
-
|
|
30308
|
-
|
|
30309
|
-
|
|
30310
|
-
|
|
30311
|
-
|
|
30312
|
-
|
|
30313
|
-
|
|
30314
|
-
|
|
30315
|
-
const templateContext = {
|
|
30316
|
-
projectName
|
|
30317
|
-
};
|
|
30318
|
-
await createRestApiScaffolding(targetDir, templateContext);
|
|
30319
|
-
consola.info("REST API project scaffolding complete. Run 'npm install' to install dependencies.");
|
|
30320
|
-
} else {
|
|
30321
|
-
throw new Error('Project type "graphql" is not yet supported. Supported types: webapp, api');
|
|
30322
|
-
}
|
|
30462
|
+
if (!isSupportedProjectType(projectType)) {
|
|
30463
|
+
const supported = SUPPORTED_PROJECT_TYPES.join(", ");
|
|
30464
|
+
throw new Error(`Project type "${projectType}" is not yet supported. Supported types: ${supported}`);
|
|
30465
|
+
}
|
|
30466
|
+
const config = PROJECT_TYPE_CONFIGS[projectType];
|
|
30467
|
+
const { projectName } = await getValidatedProjectName(promptFn, context.args.name, config.label, config.placeholder);
|
|
30468
|
+
const templateContext = {
|
|
30469
|
+
projectName
|
|
30470
|
+
};
|
|
30471
|
+
await scaffoldProject(projectType, targetDir, templateContext);
|
|
30472
|
+
consola.info(`${config.label} project scaffolding complete. Run 'npm install' to install dependencies.`);
|
|
30323
30473
|
}
|
|
30324
30474
|
});
|
|
30325
30475
|
|