@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.
Files changed (28) hide show
  1. package/api/copilot-with-fastify/biome.json +1 -1
  2. package/cli/copilot-with-citty/.devcontainer/devcontainer.json +76 -0
  3. package/cli/copilot-with-citty/.editorconfig +16 -0
  4. package/cli/copilot-with-citty/.github/ISSUE_TEMPLATE/feature-to-spec.yml +54 -0
  5. package/cli/copilot-with-citty/.github/copilot-instructions.md +228 -0
  6. package/cli/copilot-with-citty/.github/instructions/pipeline.instructions.md +92 -0
  7. package/cli/copilot-with-citty/.github/instructions/software-architecture.instructions.md +166 -0
  8. package/cli/copilot-with-citty/.github/instructions/spec.instructions.md +127 -0
  9. package/cli/copilot-with-citty/.github/instructions/test.instructions.md +157 -0
  10. package/cli/copilot-with-citty/.github/specs/README.md +84 -0
  11. package/cli/copilot-with-citty/.github/workflows/assign-copilot.yml +59 -0
  12. package/cli/copilot-with-citty/.github/workflows/ci.yml +67 -0
  13. package/cli/copilot-with-citty/.nvmrc +1 -0
  14. package/cli/copilot-with-citty/.vscode/extensions.json +13 -0
  15. package/cli/copilot-with-citty/.vscode/launch.json +25 -0
  16. package/cli/copilot-with-citty/.vscode/mcp.json +19 -0
  17. package/cli/copilot-with-citty/.yamllint +18 -0
  18. package/cli/copilot-with-citty/biome.json +31 -0
  19. package/cli/copilot-with-citty/package.json +29 -0
  20. package/cli/copilot-with-citty/tsconfig.json +28 -0
  21. package/cli/copilot-with-citty/vitest.config.ts +15 -0
  22. package/cli/copilot-with-citty/vitest.setup.ts +2 -0
  23. package/dist/index.js +205 -55
  24. package/dist/index.js.map +1 -1
  25. package/dist/mcp-server.js +3 -0
  26. package/dist/mcp-server.js.map +1 -1
  27. package/package.json +3 -2
  28. 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
- * Default CLI project filesystem structure
29135
- */ const DEFAULT_CLI_STRUCTURE = {
29136
- nodes: [
29137
- {
29138
- type: "directory",
29139
- path: ".github/instructions"
29140
- },
29141
- {
29142
- type: "file",
29143
- path: ".github/copilot-instructions.md",
29144
- content: ""
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: webapp structure is lazy-loaded only when requested
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 has a default structure
29656
+ // Lazy-load CLI structure only when requested
29512
29657
  if (projectType === "cli") {
29513
- return config.structures?.cli || DEFAULT_CLI_STRUCTURE;
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 createWebappScaffolding(targetDir, templateContext) {
30428
+ async function scaffoldProject(projectType, targetDir, templateContext) {
30429
+ const config = PROJECT_TYPE_CONFIGS[projectType];
30266
30430
  try {
30267
- const webappStructure = await getProjectStructure("webapp");
30268
- await createFilesystemStructure(webappStructure, targetDir, templateContext);
30431
+ const structure = await getProjectStructure(config.structureKey);
30432
+ await createFilesystemStructure(structure, targetDir, templateContext);
30269
30433
  } catch (error) {
30270
- consola.error(`Failed to create webapp scaffolding: ${formatErrorMessage(error)}`);
30434
+ consola.error(`Failed to create ${config.label} scaffolding: ${formatErrorMessage(error)}`);
30271
30435
  throw error;
30272
30436
  }
30273
30437
  }
30274
- async function createRestApiScaffolding(targetDir, templateContext) {
30275
- try {
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 === "cli") {
30305
- throw new Error('Project type "cli" is not yet supported. Supported types: webapp, api');
30306
- } else if (projectType === "webapp") {
30307
- const { projectName } = await getValidatedProjectName(promptFn, context.args.name, "webapp", "my-webapp");
30308
- const templateContext = {
30309
- projectName
30310
- };
30311
- await createWebappScaffolding(targetDir, templateContext);
30312
- consola.info("Webapp project scaffolding complete. Run 'npm install' to install dependencies.");
30313
- } else if (projectType === "api") {
30314
- const { projectName } = await getValidatedProjectName(promptFn, context.args.name, "REST API", "my-rest-api");
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