@lousy-agents/cli 2.11.0 → 3.1.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
@@ -32630,6 +32630,15 @@ const RulesetSchema = schemas_object({
32630
32630
  enforcement: schemas_string(),
32631
32631
  rules: schemas_array(RulesetRuleSchema).optional()
32632
32632
  });
32633
+ const RepoSecuritySchema = schemas_object({
32634
+ // biome-ignore lint/style/useNamingConvention: GitHub API schema requires snake_case
32635
+ security_and_analysis: schemas_object({
32636
+ // biome-ignore lint/style/useNamingConvention: GitHub API schema requires snake_case
32637
+ advanced_security: schemas_object({
32638
+ status: schemas_string()
32639
+ })
32640
+ }).optional()
32641
+ });
32633
32642
  /**
32634
32643
  * Parses a GitHub remote URL to extract owner and repo name
32635
32644
  */ function parseRepoFromRemoteUrl(remoteUrl) {
@@ -32704,6 +32713,24 @@ function defaultExec(command, args, options) {
32704
32713
  return null;
32705
32714
  }
32706
32715
  }
32716
+ async hasAdvancedSecurity(owner, repo) {
32717
+ if (!this.octokit) {
32718
+ return false;
32719
+ }
32720
+ try {
32721
+ const { data } = await this.octokit.rest.repos.get({
32722
+ owner,
32723
+ repo
32724
+ });
32725
+ const parsed = RepoSecuritySchema.safeParse(data);
32726
+ if (!parsed.success) {
32727
+ return false;
32728
+ }
32729
+ return parsed.data.security_and_analysis?.advanced_security?.status === "enabled";
32730
+ } catch {
32731
+ return false;
32732
+ }
32733
+ }
32707
32734
  async listRulesets(owner, repo) {
32708
32735
  if (!this.octokit) {
32709
32736
  throw new Error("Not authenticated");
@@ -32737,18 +32764,16 @@ function defaultExec(command, args, options) {
32737
32764
  }
32738
32765
  /**
32739
32766
  * Resolves a GitHub token from GH_TOKEN/GITHUB_TOKEN env vars, with gh CLI fallback
32740
- */ async function resolveGitHubToken() {
32741
- const envToken = process.env.GH_TOKEN || process.env.GITHUB_TOKEN;
32767
+ */ async function resolveGitHubToken(exec = defaultExec) {
32768
+ const envToken = process.env.GH_TOKEN?.trim() || process.env.GITHUB_TOKEN?.trim();
32742
32769
  if (envToken) {
32743
32770
  return envToken;
32744
32771
  }
32745
32772
  try {
32746
- const { stdout } = await execFileAsync("gh", [
32773
+ const { stdout } = await exec("gh", [
32747
32774
  "auth",
32748
32775
  "token"
32749
- ], {
32750
- encoding: "utf-8"
32751
- });
32776
+ ]);
32752
32777
  const token = stdout.trim();
32753
32778
  return token || null;
32754
32779
  } catch {
@@ -33671,8 +33696,44 @@ function isCopilotCodeScanningRule(rule) {
33671
33696
  return findCopilotRuleset(rulesets) !== undefined;
33672
33697
  }
33673
33698
  /**
33674
- * Builds a ruleset payload for enabling Copilot code review
33675
- */ function buildCopilotReviewRulesetPayload() {
33699
+ * Builds a ruleset payload for enabling Copilot code review.
33700
+ * Includes code_scanning rules configured with CodeQL and Copilot Autofix when GitHub Advanced Security is enabled.
33701
+ */ function buildCopilotReviewRulesetPayload(options) {
33702
+ const rules = [
33703
+ {
33704
+ type: "copilot_code_review",
33705
+ parameters: {
33706
+ // biome-ignore lint/style/useNamingConvention: GitHub API schema requires snake_case
33707
+ review_on_push: true,
33708
+ // biome-ignore lint/style/useNamingConvention: GitHub API schema requires snake_case
33709
+ review_draft_pull_requests: true
33710
+ }
33711
+ }
33712
+ ];
33713
+ if (options.advancedSecurityEnabled) {
33714
+ rules.push({
33715
+ type: "code_scanning",
33716
+ parameters: {
33717
+ // biome-ignore lint/style/useNamingConvention: GitHub API schema requires snake_case
33718
+ code_scanning_tools: [
33719
+ {
33720
+ tool: "CodeQL",
33721
+ // biome-ignore lint/style/useNamingConvention: GitHub API schema requires snake_case
33722
+ security_alerts_threshold: "high_or_higher",
33723
+ // biome-ignore lint/style/useNamingConvention: GitHub API schema requires snake_case
33724
+ alerts_threshold: "errors"
33725
+ },
33726
+ {
33727
+ tool: "Copilot Autofix",
33728
+ // biome-ignore lint/style/useNamingConvention: GitHub API schema requires snake_case
33729
+ security_alerts_threshold: "high_or_higher",
33730
+ // biome-ignore lint/style/useNamingConvention: GitHub API schema requires snake_case
33731
+ alerts_threshold: "errors"
33732
+ }
33733
+ ]
33734
+ }
33735
+ });
33736
+ }
33676
33737
  return {
33677
33738
  name: "Copilot Code Review",
33678
33739
  enforcement: "active",
@@ -33688,32 +33749,7 @@ function isCopilotCodeScanningRule(rule) {
33688
33749
  exclude: []
33689
33750
  }
33690
33751
  },
33691
- rules: [
33692
- {
33693
- type: "copilot_code_review",
33694
- parameters: {
33695
- // biome-ignore lint/style/useNamingConvention: GitHub API schema requires snake_case
33696
- review_on_push: true,
33697
- // biome-ignore lint/style/useNamingConvention: GitHub API schema requires snake_case
33698
- review_draft_pull_requests: true
33699
- }
33700
- },
33701
- {
33702
- type: "code_scanning",
33703
- parameters: {
33704
- // biome-ignore lint/style/useNamingConvention: GitHub API schema requires snake_case
33705
- code_scanning_tools: [
33706
- {
33707
- tool: "Copilot Autofix",
33708
- // biome-ignore lint/style/useNamingConvention: GitHub API schema requires snake_case
33709
- security_alerts_threshold: "high_or_higher",
33710
- // biome-ignore lint/style/useNamingConvention: GitHub API schema requires snake_case
33711
- alerts_threshold: "errors"
33712
- }
33713
- ]
33714
- }
33715
- }
33716
- ]
33752
+ rules
33717
33753
  };
33718
33754
  }
33719
33755
  /**
@@ -34683,7 +34719,10 @@ async function checkAndPromptRuleset(rulesetGateway, targetDir, prompt) {
34683
34719
  return;
34684
34720
  }
34685
34721
  try {
34686
- const payload = buildCopilotReviewRulesetPayload();
34722
+ const advancedSecurityEnabled = await rulesetGateway.hasAdvancedSecurity(repoInfo.owner, repoInfo.repo);
34723
+ const payload = buildCopilotReviewRulesetPayload({
34724
+ advancedSecurityEnabled
34725
+ });
34687
34726
  await rulesetGateway.createRuleset(repoInfo.owner, repoInfo.repo, payload);
34688
34727
  consola.success(`Created Copilot PR review ruleset: "${payload.name}"`);
34689
34728
  } catch (error) {