@lousy-agents/cli 2.3.4 → 2.4.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/dist/index.js CHANGED
@@ -11799,6 +11799,27 @@ const consola = dist_createConsola();
11799
11799
  return new FileSystemAgentFileGateway();
11800
11800
  }
11801
11801
 
11802
+ ;// CONCATENATED MODULE: ./src/entities/copilot-setup.ts
11803
+ /**
11804
+ * Core domain entities for the Copilot Setup Steps feature.
11805
+ * These are the fundamental types that represent the business domain.
11806
+ */ /**
11807
+ * Types of version files supported for detection
11808
+ */ /**
11809
+ * Node.js package manager types (in priority order: npm > yarn > pnpm)
11810
+ */ const NODE_PACKAGE_MANAGERS = [
11811
+ "npm",
11812
+ "yarn",
11813
+ "pnpm"
11814
+ ];
11815
+ /**
11816
+ * Python package manager types (in priority order)
11817
+ */ const PYTHON_PACKAGE_MANAGERS = [
11818
+ "poetry",
11819
+ "pipenv",
11820
+ "pip"
11821
+ ];
11822
+
11802
11823
  // EXTERNAL MODULE: external "node:fs"
11803
11824
  var external_node_fs_ = __webpack_require__(3024);
11804
11825
  // EXTERNAL MODULE: ./node_modules/pathe/dist/shared/pathe.M-eThtNZ.mjs
@@ -14086,12 +14107,102 @@ async function watchConfig(options) {
14086
14107
  "actions/setup-ruby",
14087
14108
  "jdx/mise-action"
14088
14109
  ];
14110
+ /**
14111
+ * Default package manager mappings
14112
+ * Based on Dependabot supported ecosystems
14113
+ */ const DEFAULT_PACKAGE_MANAGERS = [
14114
+ // Node.js package managers
14115
+ {
14116
+ type: "npm",
14117
+ manifestFile: "package.json",
14118
+ lockfile: "package-lock.json",
14119
+ installCommand: "npm ci"
14120
+ },
14121
+ {
14122
+ type: "yarn",
14123
+ manifestFile: "package.json",
14124
+ lockfile: "yarn.lock",
14125
+ installCommand: "yarn install --frozen-lockfile"
14126
+ },
14127
+ {
14128
+ type: "pnpm",
14129
+ manifestFile: "package.json",
14130
+ lockfile: "pnpm-lock.yaml",
14131
+ installCommand: "pnpm install --frozen-lockfile"
14132
+ },
14133
+ // Python package managers
14134
+ {
14135
+ type: "pip",
14136
+ manifestFile: "requirements.txt",
14137
+ installCommand: "pip install -r requirements.txt"
14138
+ },
14139
+ {
14140
+ type: "pipenv",
14141
+ manifestFile: "Pipfile",
14142
+ lockfile: "Pipfile.lock",
14143
+ installCommand: "pipenv install --deploy"
14144
+ },
14145
+ {
14146
+ type: "poetry",
14147
+ manifestFile: "pyproject.toml",
14148
+ lockfile: "poetry.lock",
14149
+ requiresLockfile: true,
14150
+ installCommand: "poetry install --no-root"
14151
+ },
14152
+ // Ruby
14153
+ {
14154
+ type: "bundler",
14155
+ manifestFile: "Gemfile",
14156
+ lockfile: "Gemfile.lock",
14157
+ installCommand: "bundle install"
14158
+ },
14159
+ // Rust
14160
+ {
14161
+ type: "cargo",
14162
+ manifestFile: "Cargo.toml",
14163
+ lockfile: "Cargo.lock",
14164
+ installCommand: "cargo build"
14165
+ },
14166
+ // PHP
14167
+ {
14168
+ type: "composer",
14169
+ manifestFile: "composer.json",
14170
+ lockfile: "composer.lock",
14171
+ installCommand: "composer install"
14172
+ },
14173
+ // Java
14174
+ {
14175
+ type: "maven",
14176
+ manifestFile: "pom.xml",
14177
+ installCommand: "mvn install -DskipTests"
14178
+ },
14179
+ {
14180
+ type: "gradle",
14181
+ manifestFile: "build.gradle",
14182
+ installCommand: "gradle build -x test"
14183
+ },
14184
+ // Go
14185
+ {
14186
+ type: "gomod",
14187
+ manifestFile: "go.mod",
14188
+ lockfile: "go.sum",
14189
+ installCommand: "go mod download"
14190
+ },
14191
+ // Dart/Flutter
14192
+ {
14193
+ type: "pub",
14194
+ manifestFile: "pubspec.yaml",
14195
+ lockfile: "pubspec.lock",
14196
+ installCommand: "dart pub get"
14197
+ }
14198
+ ];
14089
14199
  /**
14090
14200
  * Default copilot-setup configuration
14091
14201
  */ const DEFAULT_CONFIG = {
14092
14202
  versionFiles: DEFAULT_VERSION_FILES,
14093
14203
  setupActions: DEFAULT_SETUP_ACTIONS,
14094
- setupActionPatterns: DEFAULT_SETUP_ACTION_PATTERNS
14204
+ setupActionPatterns: DEFAULT_SETUP_ACTION_PATTERNS,
14205
+ packageManagers: DEFAULT_PACKAGE_MANAGERS
14095
14206
  };
14096
14207
  /**
14097
14208
  * Loads the copilot-setup configuration using c12
@@ -14150,6 +14261,7 @@ async function watchConfig(options) {
14150
14261
 
14151
14262
 
14152
14263
 
14264
+
14153
14265
  /**
14154
14266
  * Reads the content of a version file and trims whitespace
14155
14267
  */ async function readVersionFileContent(filePath) {
@@ -14167,9 +14279,21 @@ async function watchConfig(options) {
14167
14279
  return this.config;
14168
14280
  }
14169
14281
  async detectEnvironment(targetDir) {
14170
- const miseTomlPath = (0,external_node_path_.join)(targetDir, "mise.toml");
14171
- const hasMise = await fileExists(miseTomlPath);
14172
14282
  const config = await this.getConfig();
14283
+ const hasMise = await this.detectMise(targetDir);
14284
+ const versionFiles = await this.detectVersionFiles(targetDir, config);
14285
+ const packageManagers = await this.detectPackageManagers(targetDir, config);
14286
+ return {
14287
+ hasMise,
14288
+ versionFiles,
14289
+ packageManagers
14290
+ };
14291
+ }
14292
+ async detectMise(targetDir) {
14293
+ const miseTomlPath = (0,external_node_path_.join)(targetDir, "mise.toml");
14294
+ return fileExists(miseTomlPath);
14295
+ }
14296
+ async detectVersionFiles(targetDir, config) {
14173
14297
  const filenameToType = getVersionFilenameToTypeMap(config);
14174
14298
  const versionFiles = [];
14175
14299
  for (const fileConfig of config.versionFiles){
@@ -14183,10 +14307,109 @@ async function watchConfig(options) {
14183
14307
  });
14184
14308
  }
14185
14309
  }
14186
- return {
14187
- hasMise,
14188
- versionFiles
14189
- };
14310
+ return versionFiles;
14311
+ }
14312
+ async detectPackageManagers(targetDir, config) {
14313
+ const packageManagers = [];
14314
+ // Helper to check if a package manager type is in a list
14315
+ const isPackageManagerType = (pm, types)=>types.includes(pm.type);
14316
+ const nodePackageManagers = config.packageManagers.filter((pm)=>isPackageManagerType(pm, NODE_PACKAGE_MANAGERS));
14317
+ const pythonPackageManagers = config.packageManagers.filter((pm)=>isPackageManagerType(pm, PYTHON_PACKAGE_MANAGERS));
14318
+ const otherPackageManagers = config.packageManagers.filter((pm)=>!isPackageManagerType(pm, NODE_PACKAGE_MANAGERS) && !isPackageManagerType(pm, PYTHON_PACKAGE_MANAGERS));
14319
+ // Detect Node.js package manager (with prioritization)
14320
+ const nodePackageManager = await this.detectNodePackageManager(targetDir, nodePackageManagers);
14321
+ if (nodePackageManager) {
14322
+ packageManagers.push(nodePackageManager);
14323
+ }
14324
+ // Detect Python package manager (with prioritization)
14325
+ const pythonPackageManager = await this.detectPythonPackageManager(targetDir, pythonPackageManagers);
14326
+ if (pythonPackageManager) {
14327
+ packageManagers.push(pythonPackageManager);
14328
+ }
14329
+ // Detect other package managers
14330
+ const otherDetectedManagers = await this.detectOtherPackageManagers(targetDir, otherPackageManagers);
14331
+ packageManagers.push(...otherDetectedManagers);
14332
+ return packageManagers;
14333
+ }
14334
+ async detectNodePackageManager(targetDir, nodePackageManagers) {
14335
+ const packageJsonPath = (0,external_node_path_.join)(targetDir, "package.json");
14336
+ if (!await fileExists(packageJsonPath)) {
14337
+ return null;
14338
+ }
14339
+ // Priority order for Node.js package managers: npm > yarn > pnpm
14340
+ const lockfileOrder = [
14341
+ "npm",
14342
+ "yarn",
14343
+ "pnpm"
14344
+ ];
14345
+ for (const pmType of lockfileOrder){
14346
+ const pmConfig = nodePackageManagers.find((pm)=>pm.type === pmType);
14347
+ if (!pmConfig?.lockfile) {
14348
+ continue;
14349
+ }
14350
+ const lockfilePath = (0,external_node_path_.join)(targetDir, pmConfig.lockfile);
14351
+ if (await fileExists(lockfilePath)) {
14352
+ return {
14353
+ type: pmConfig.type,
14354
+ filename: pmConfig.manifestFile,
14355
+ lockfile: pmConfig.lockfile
14356
+ };
14357
+ }
14358
+ }
14359
+ // Default to npm if no lockfile found
14360
+ const npmConfig = nodePackageManagers.find((pm)=>pm.type === "npm");
14361
+ if (npmConfig) {
14362
+ return {
14363
+ type: npmConfig.type,
14364
+ filename: npmConfig.manifestFile,
14365
+ lockfile: undefined
14366
+ };
14367
+ }
14368
+ return null;
14369
+ }
14370
+ async detectPythonPackageManager(targetDir, pythonPackageManagers) {
14371
+ // Priority order for Python package managers: poetry > pipenv > pip
14372
+ for (const pmType of PYTHON_PACKAGE_MANAGERS){
14373
+ const pmConfig = pythonPackageManagers.find((pm)=>pm.type === pmType);
14374
+ if (!pmConfig) {
14375
+ continue;
14376
+ }
14377
+ const manifestPath = (0,external_node_path_.join)(targetDir, pmConfig.manifestFile);
14378
+ if (await fileExists(manifestPath)) {
14379
+ const lockfilePath = pmConfig.lockfile ? (0,external_node_path_.join)(targetDir, pmConfig.lockfile) : undefined;
14380
+ const hasLockfile = lockfilePath ? await fileExists(lockfilePath) : false;
14381
+ // Skip if lockfile is required but not present
14382
+ if (pmConfig.requiresLockfile && !hasLockfile) {
14383
+ continue;
14384
+ }
14385
+ return {
14386
+ type: pmConfig.type,
14387
+ filename: pmConfig.manifestFile,
14388
+ lockfile: hasLockfile ? pmConfig.lockfile : undefined
14389
+ };
14390
+ }
14391
+ }
14392
+ return null;
14393
+ }
14394
+ async detectOtherPackageManagers(targetDir, otherPackageManagers) {
14395
+ const packageManagers = [];
14396
+ for (const pmConfig of otherPackageManagers){
14397
+ const manifestPath = (0,external_node_path_.join)(targetDir, pmConfig.manifestFile);
14398
+ if (await fileExists(manifestPath)) {
14399
+ const lockfilePath = pmConfig.lockfile ? (0,external_node_path_.join)(targetDir, pmConfig.lockfile) : undefined;
14400
+ const hasLockfile = lockfilePath ? await fileExists(lockfilePath) : false;
14401
+ // Skip if lockfile is required but not present
14402
+ if (pmConfig.requiresLockfile && !hasLockfile) {
14403
+ continue;
14404
+ }
14405
+ packageManagers.push({
14406
+ type: pmConfig.type,
14407
+ filename: pmConfig.manifestFile,
14408
+ lockfile: hasLockfile ? pmConfig.lockfile : undefined
14409
+ });
14410
+ }
14411
+ }
14412
+ return packageManagers;
14190
14413
  }
14191
14414
  }
14192
14415
  /**
@@ -14538,7 +14761,7 @@ var dist = __webpack_require__(1198);
14538
14761
  /**
14539
14762
  * Use case for building setup step candidates from environment detection.
14540
14763
  * This module handles the logic of determining which GitHub Actions
14541
- * setup steps should be added based on detected version files.
14764
+ * setup steps should be added based on detected version files and package managers.
14542
14765
  */
14543
14766
 
14544
14767
  /**
@@ -14563,7 +14786,12 @@ var dist = __webpack_require__(1198);
14563
14786
  return candidates;
14564
14787
  }
14565
14788
  // Otherwise, add individual setup actions for each version file
14566
- return buildCandidatesFromVersionFiles(environment.versionFiles, versionTypeToAction, versionFileConfigKeys, versionGateway);
14789
+ const setupCandidates = await buildCandidatesFromVersionFiles(environment.versionFiles, versionTypeToAction, versionFileConfigKeys, versionGateway);
14790
+ candidates.push(...setupCandidates);
14791
+ // Add install steps for detected package managers
14792
+ const installCandidates = buildInstallCandidatesFromPackageManagers(environment.packageManagers, loadedConfig);
14793
+ candidates.push(...installCandidates);
14794
+ return candidates;
14567
14795
  }
14568
14796
  /**
14569
14797
  * Builds setup step candidates from individual version files
@@ -14598,6 +14826,59 @@ var dist = __webpack_require__(1198);
14598
14826
  }
14599
14827
  return candidates;
14600
14828
  }
14829
+ /**
14830
+ * Builds install step candidates from detected package managers
14831
+ * @param packageManagers Array of detected package managers
14832
+ * @param config Configuration for package manager mappings
14833
+ * @returns Array of install step candidates
14834
+ */ function buildInstallCandidatesFromPackageManagers(packageManagers, config) {
14835
+ const candidates = [];
14836
+ const addedTypes = new Set();
14837
+ for (const pm of packageManagers){
14838
+ // Skip if we've already added this package manager type
14839
+ if (addedTypes.has(pm.type)) {
14840
+ continue;
14841
+ }
14842
+ addedTypes.add(pm.type);
14843
+ // Find the config for this package manager
14844
+ const pmConfig = config.packageManagers.find((c)=>c.type === pm.type);
14845
+ if (!pmConfig) {
14846
+ continue;
14847
+ }
14848
+ // Determine a descriptive name for the install step
14849
+ const stepName = getInstallStepName(pm.type);
14850
+ // Create install step candidate
14851
+ // Note: Empty action string indicates this is a run step (uses 'run' field instead of 'uses')
14852
+ // This is checked in workflow-generator.ts buildStepFromCandidate()
14853
+ candidates.push({
14854
+ action: "",
14855
+ source: "version-file",
14856
+ name: stepName,
14857
+ run: pmConfig.installCommand
14858
+ });
14859
+ }
14860
+ return candidates;
14861
+ }
14862
+ /**
14863
+ * Gets a descriptive name for an install step based on package manager type
14864
+ */ function getInstallStepName(packageManagerType) {
14865
+ const names = {
14866
+ npm: "Install Node.js dependencies",
14867
+ yarn: "Install Node.js dependencies",
14868
+ pnpm: "Install Node.js dependencies",
14869
+ pip: "Install Python dependencies",
14870
+ pipenv: "Install Python dependencies",
14871
+ poetry: "Install Python dependencies",
14872
+ bundler: "Install Ruby dependencies",
14873
+ cargo: "Build Rust project",
14874
+ composer: "Install PHP dependencies",
14875
+ maven: "Install Java dependencies",
14876
+ gradle: "Build Gradle project",
14877
+ gomod: "Download Go dependencies",
14878
+ pub: "Install Dart dependencies"
14879
+ };
14880
+ return names[packageManagerType] || "Install dependencies";
14881
+ }
14601
14882
 
14602
14883
  ;// CONCATENATED MODULE: ./node_modules/@github-actions-workflow-ts/lib/dist/esm/workflow/index.js
14603
14884
  /**
@@ -15146,11 +15427,22 @@ Example resolved format: actions/setup-node@1a2b3c4d5e6f # v4.0.0`;
15146
15427
  * @param options Optional conversion options for placeholders and resolved versions
15147
15428
  * @returns A typed Step object
15148
15429
  */ function buildStepFromCandidate(candidate, options) {
15430
+ // Handle run steps (install commands)
15431
+ // Run steps have a 'run' field and no action (or empty action string)
15432
+ if (candidate.run && !candidate.action) {
15433
+ const stepProps = {
15434
+ name: candidate.name || "Run command",
15435
+ run: candidate.run
15436
+ };
15437
+ // Type assertion is safe here - Step constructor accepts both 'uses' and 'run' at runtime
15438
+ return new Step(stepProps);
15439
+ }
15440
+ // Handle action steps (uses)
15149
15441
  const version = getVersionForAction(candidate.action, candidate.version, options);
15150
15442
  const usesValue = buildUsesValue(candidate.action, version, options);
15151
15443
  const withConfig = candidate.config && Object.keys(candidate.config).length > 0 ? candidate.config : undefined;
15152
15444
  const stepProps = {
15153
- name: generateStepName(candidate.action),
15445
+ name: candidate.name || generateStepName(candidate.action),
15154
15446
  uses: usesValue,
15155
15447
  with: withConfig
15156
15448
  };