@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.
- 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 +224 -59
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.js +32 -1
- package/dist/mcp-server.js.map +1 -1
- package/package.json +10 -9
- package/ui/copilot-with-react/biome.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14636,6 +14636,15 @@ var dist = __webpack_require__(1198);
|
|
|
14636
14636
|
* })
|
|
14637
14637
|
* workflow.addJob(testJob)
|
|
14638
14638
|
* ```
|
|
14639
|
+
*
|
|
14640
|
+
* @example
|
|
14641
|
+
* ```typescript
|
|
14642
|
+
* // With custom output path
|
|
14643
|
+
* const workflow = new Workflow('deploy', {
|
|
14644
|
+
* name: 'Deploy',
|
|
14645
|
+
* on: { push: { branches: ['main'] } },
|
|
14646
|
+
* }, { outputPath: 'packages/app-a/.github/workflows' })
|
|
14647
|
+
* ```
|
|
14639
14648
|
*/
|
|
14640
14649
|
class Workflow {
|
|
14641
14650
|
workflow;
|
|
@@ -14643,6 +14652,11 @@ class Workflow {
|
|
|
14643
14652
|
* The filename of the workflow e.g. `main.yml`
|
|
14644
14653
|
*/
|
|
14645
14654
|
filename;
|
|
14655
|
+
/**
|
|
14656
|
+
* Custom output path for this workflow.
|
|
14657
|
+
* If set, overrides any config file settings.
|
|
14658
|
+
*/
|
|
14659
|
+
outputPath;
|
|
14646
14660
|
addEnvs(envs) {
|
|
14647
14661
|
if (this.workflow.env && typeof this.workflow.env === 'object')
|
|
14648
14662
|
this.workflow.env = {
|
|
@@ -14667,11 +14681,12 @@ class Workflow {
|
|
|
14667
14681
|
};
|
|
14668
14682
|
return this;
|
|
14669
14683
|
}
|
|
14670
|
-
constructor(filename, workflowProps) {
|
|
14684
|
+
constructor(filename, workflowProps, options) {
|
|
14671
14685
|
this.filename = filename;
|
|
14672
14686
|
this.workflow = {
|
|
14673
14687
|
...workflowProps,
|
|
14674
14688
|
};
|
|
14689
|
+
this.outputPath = options?.outputPath;
|
|
14675
14690
|
}
|
|
14676
14691
|
}
|
|
14677
14692
|
//# sourceMappingURL=index.js.map
|
|
@@ -15229,6 +15244,7 @@ Example resolved format: actions/setup-node@1a2b3c4d5e6f # v4.0.0`;
|
|
|
15229
15244
|
const workflow = new Workflow("copilot-setup-steps.yml", {
|
|
15230
15245
|
name: "Copilot Setup Steps",
|
|
15231
15246
|
on: {
|
|
15247
|
+
// biome-ignore lint/style/useNamingConvention: GitHub Actions YAML schema requires snake_case
|
|
15232
15248
|
workflow_dispatch: {},
|
|
15233
15249
|
push: {
|
|
15234
15250
|
branches: [
|
|
@@ -15238,6 +15254,7 @@ Example resolved format: actions/setup-node@1a2b3c4d5e6f # v4.0.0`;
|
|
|
15238
15254
|
".github/workflows/copilot-setup-steps.yml"
|
|
15239
15255
|
]
|
|
15240
15256
|
},
|
|
15257
|
+
// biome-ignore lint/style/useNamingConvention: GitHub Actions YAML schema requires snake_case
|
|
15241
15258
|
pull_request: {
|
|
15242
15259
|
branches: [
|
|
15243
15260
|
"main"
|
|
@@ -29115,21 +29132,168 @@ const config_dirname = (0,external_node_path_.dirname)(config_filename);
|
|
|
29115
29132
|
const PROJECT_ROOT = (0,external_node_path_.join)(config_dirname, "..", "..");
|
|
29116
29133
|
const WEBAPP_TEMPLATE_DIR = (0,external_node_path_.join)(PROJECT_ROOT, "ui", "copilot-with-react");
|
|
29117
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");
|
|
29118
29136
|
/**
|
|
29119
|
-
*
|
|
29120
|
-
*/
|
|
29121
|
-
|
|
29122
|
-
|
|
29123
|
-
|
|
29124
|
-
|
|
29125
|
-
|
|
29126
|
-
|
|
29127
|
-
|
|
29128
|
-
|
|
29129
|
-
|
|
29130
|
-
|
|
29131
|
-
|
|
29132
|
-
}
|
|
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
|
+
}
|
|
29133
29297
|
/**
|
|
29134
29298
|
* Helper function to read template file content
|
|
29135
29299
|
* @throws Error if template file cannot be read
|
|
@@ -29463,20 +29627,16 @@ const RESTAPI_TEMPLATE_DIR = (0,external_node_path_.join)(PROJECT_ROOT, "api", "
|
|
|
29463
29627
|
/**
|
|
29464
29628
|
* Loads the configuration for the init command
|
|
29465
29629
|
* Falls back to defaults if no configuration is found
|
|
29466
|
-
* Note:
|
|
29630
|
+
* Note: project structures are lazy-loaded only when requested
|
|
29467
29631
|
*/ async function loadInitConfig() {
|
|
29468
29632
|
const { config } = await loadConfig({
|
|
29469
29633
|
name: "lousy-agents",
|
|
29470
29634
|
defaults: {
|
|
29471
|
-
structures: {
|
|
29472
|
-
cli: DEFAULT_CLI_STRUCTURE
|
|
29473
|
-
}
|
|
29635
|
+
structures: {}
|
|
29474
29636
|
}
|
|
29475
29637
|
});
|
|
29476
29638
|
return config || {
|
|
29477
|
-
structures: {
|
|
29478
|
-
cli: DEFAULT_CLI_STRUCTURE
|
|
29479
|
-
}
|
|
29639
|
+
structures: {}
|
|
29480
29640
|
};
|
|
29481
29641
|
}
|
|
29482
29642
|
/**
|
|
@@ -29493,9 +29653,9 @@ const RESTAPI_TEMPLATE_DIR = (0,external_node_path_.join)(PROJECT_ROOT, "api", "
|
|
|
29493
29653
|
if (projectType === "api") {
|
|
29494
29654
|
return config.structures?.api || buildRestApiStructure();
|
|
29495
29655
|
}
|
|
29496
|
-
// CLI
|
|
29656
|
+
// Lazy-load CLI structure only when requested
|
|
29497
29657
|
if (projectType === "cli") {
|
|
29498
|
-
return config.structures?.cli ||
|
|
29658
|
+
return config.structures?.cli || buildCliStructure();
|
|
29499
29659
|
}
|
|
29500
29660
|
// GraphQL is not yet implemented
|
|
29501
29661
|
throw new Error(`Project type "${projectType}" is not yet supported. Supported types: cli, webapp, api`);
|
|
@@ -29678,18 +29838,18 @@ function compileBody(buff) {
|
|
|
29678
29838
|
let returnStr = "";
|
|
29679
29839
|
for (; i < buffLength; i++) {
|
|
29680
29840
|
const currentBlock = buff[i];
|
|
29681
|
-
if (typeof currentBlock === "string") returnStr += "__eta.res+='" + currentBlock + "'
|
|
29841
|
+
if (typeof currentBlock === "string") returnStr += "__eta.res+='" + currentBlock + "';\n";
|
|
29682
29842
|
else {
|
|
29683
29843
|
const type = currentBlock.t;
|
|
29684
29844
|
let content = currentBlock.val || "";
|
|
29685
29845
|
if (config.debug) returnStr += "__eta.line=" + currentBlock.lineNo + "\n";
|
|
29686
29846
|
if (type === "r") {
|
|
29687
29847
|
if (config.autoFilter) content = "__eta.f(" + content + ")";
|
|
29688
|
-
returnStr += "__eta.res+=" + content + "
|
|
29848
|
+
returnStr += "__eta.res+=" + content + ";\n";
|
|
29689
29849
|
} else if (type === "i") {
|
|
29690
29850
|
if (config.autoFilter) content = "__eta.f(" + content + ")";
|
|
29691
29851
|
if (config.autoEscape) content = "__eta.e(" + content + ")";
|
|
29692
|
-
returnStr += "__eta.res+=" + content + "
|
|
29852
|
+
returnStr += "__eta.res+=" + content + ";\n";
|
|
29693
29853
|
} else if (type === "e") returnStr += content + "\n";
|
|
29694
29854
|
}
|
|
29695
29855
|
}
|
|
@@ -30213,8 +30373,26 @@ const ProjectTypeSchema = schemas_enum([
|
|
|
30213
30373
|
const PROJECT_TYPE_OPTIONS = ProjectTypeSchema.options;
|
|
30214
30374
|
const SUPPORTED_PROJECT_TYPES = [
|
|
30215
30375
|
"webapp",
|
|
30216
|
-
"api"
|
|
30376
|
+
"api",
|
|
30377
|
+
"cli"
|
|
30217
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
|
+
};
|
|
30218
30396
|
const initArgs = {
|
|
30219
30397
|
kind: {
|
|
30220
30398
|
type: "string",
|
|
@@ -30247,23 +30425,18 @@ async function getValidatedProjectName(promptFn, existingName, projectTypeLabel,
|
|
|
30247
30425
|
projectName
|
|
30248
30426
|
};
|
|
30249
30427
|
}
|
|
30250
|
-
async function
|
|
30428
|
+
async function scaffoldProject(projectType, targetDir, templateContext) {
|
|
30429
|
+
const config = PROJECT_TYPE_CONFIGS[projectType];
|
|
30251
30430
|
try {
|
|
30252
|
-
const
|
|
30253
|
-
await createFilesystemStructure(
|
|
30431
|
+
const structure = await getProjectStructure(config.structureKey);
|
|
30432
|
+
await createFilesystemStructure(structure, targetDir, templateContext);
|
|
30254
30433
|
} catch (error) {
|
|
30255
|
-
consola.error(`Failed to create
|
|
30434
|
+
consola.error(`Failed to create ${config.label} scaffolding: ${formatErrorMessage(error)}`);
|
|
30256
30435
|
throw error;
|
|
30257
30436
|
}
|
|
30258
30437
|
}
|
|
30259
|
-
|
|
30260
|
-
|
|
30261
|
-
const restApiStructure = await getProjectStructure("api");
|
|
30262
|
-
await createFilesystemStructure(restApiStructure, targetDir, templateContext);
|
|
30263
|
-
} catch (error) {
|
|
30264
|
-
consola.error(`Failed to create REST API scaffolding: ${formatErrorMessage(error)}`);
|
|
30265
|
-
throw error;
|
|
30266
|
-
}
|
|
30438
|
+
function isSupportedProjectType(projectType) {
|
|
30439
|
+
return SUPPORTED_PROJECT_TYPES.includes(projectType);
|
|
30267
30440
|
}
|
|
30268
30441
|
const initCommand = defineCommand({
|
|
30269
30442
|
meta: {
|
|
@@ -30286,25 +30459,17 @@ const initCommand = defineCommand({
|
|
|
30286
30459
|
}
|
|
30287
30460
|
const projectType = parseResult.data;
|
|
30288
30461
|
consola.success(`Selected project type: ${projectType}`);
|
|
30289
|
-
if (projectType
|
|
30290
|
-
|
|
30291
|
-
|
|
30292
|
-
|
|
30293
|
-
|
|
30294
|
-
|
|
30295
|
-
|
|
30296
|
-
|
|
30297
|
-
|
|
30298
|
-
|
|
30299
|
-
|
|
30300
|
-
const templateContext = {
|
|
30301
|
-
projectName
|
|
30302
|
-
};
|
|
30303
|
-
await createRestApiScaffolding(targetDir, templateContext);
|
|
30304
|
-
consola.info("REST API project scaffolding complete. Run 'npm install' to install dependencies.");
|
|
30305
|
-
} else {
|
|
30306
|
-
throw new Error('Project type "graphql" is not yet supported. Supported types: webapp, api');
|
|
30307
|
-
}
|
|
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.`);
|
|
30308
30473
|
}
|
|
30309
30474
|
});
|
|
30310
30475
|
|