@dependabit/detector 0.1.1 → 0.1.14

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.
@@ -16,11 +16,20 @@ INCLUDE these types of dependencies:
16
16
 
17
17
  EXCLUDE these (handled by dependabot):
18
18
  - NPM packages in package.json
19
- - Python packages in requirements.txt
19
+ - Python packages in requirements.txt
20
20
  - Rust crates in Cargo.toml
21
21
  - Docker images in Dockerfile
22
22
  - Any declared package manager dependencies
23
23
 
24
+ ALSO EXCLUDE (false positives):
25
+ - URLs that reference the repository itself (self-references)
26
+ - Relative file paths (e.g., CONTRIBUTING.md, docs/guide.md, ./src/utils)
27
+ - Placeholder URLs used in documentation examples (example.com, example.org, localhost)
28
+ - Internal documentation links within the same repository
29
+ - URLs with template variables or placeholders (e.g., issues/[NUMBER], user/repo)
30
+
31
+ Only return dependencies with confidence >= 0.7.
32
+
24
33
  For each dependency found, provide:
25
34
  1. url: The complete URL
26
35
  2. name: A descriptive name
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/llm/prompts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuC3B,CAAC;AAEH,MAAM,CAAC,MAAM,yBAAyB,GAAG;;;;;;;;;;;;;;qBAcpB,CAAC;AAEtB,MAAM,UAAU,qBAAqB,CACnC,WAAmB,EACnB,QAAgB,EAChB,OAAe,EACP;IACR,OAAO,yBAAyB,CAAC,OAAO,CAAC,eAAe,EAAE,WAAW,CAAC;SACnE,OAAO,CAAC,YAAY,EAAE,QAAQ,CAAC;SAC/B,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AAAA,CAClC;AAED,MAAM,CAAC,MAAM,8BAA8B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;EAyB5C,CAAC;AAEH,MAAM,UAAU,0BAA0B,CAAC,GAAW,EAAE,OAAe,EAAU;IAC/E,OAAO,8BAA8B,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AAAA,CAC3F"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/llm/prompts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgD3B,CAAC;AAEH,MAAM,CAAC,MAAM,yBAAyB,GAAG;;;;;;;;;;;;;;qBAcpB,CAAC;AAEtB,MAAM,UAAU,qBAAqB,CACnC,WAAmB,EACnB,QAAgB,EAChB,OAAe,EACP;IACR,OAAO,yBAAyB,CAAC,OAAO,CAAC,eAAe,EAAE,WAAW,CAAC;SACnE,OAAO,CAAC,YAAY,EAAE,QAAQ,CAAC;SAC/B,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AAAA,CAClC;AAED,MAAM,CAAC,MAAM,8BAA8B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;EAyB5C,CAAC;AAEH,MAAM,UAAU,0BAA0B,CAAC,GAAW,EAAE,OAAe,EAAU;IAC/E,OAAO,8BAA8B,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AAAA,CAC3F"}
@@ -1 +1 @@
1
- {"version":3,"file":"readme.d.ts","sourceRoot":"","sources":["../../src/parsers/readme.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,eAAe,GAAG,UAAU,GAAG,gBAAgB,CAAC;CACvD;AAgBD;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAc,GAAG,kBAAkB,EAAE,CAoDzF;AA6DD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,GACd,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAqCzD"}
1
+ {"version":3,"file":"readme.d.ts","sourceRoot":"","sources":["../../src/parsers/readme.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,eAAe,GAAG,UAAU,GAAG,gBAAgB,CAAC;CACvD;AAsBD;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAc,GAAG,kBAAkB,EAAE,CAoDzF;AA6DD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,GACd,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAqCzD"}
@@ -2,7 +2,7 @@
2
2
  * README Parser
3
3
  * Extracts URLs and references from README and markdown files
4
4
  */
5
- // Patterns to skip (package managers, CI badges, shields.io)
5
+ // Patterns to skip (package managers, CI badges, shields.io, placeholders)
6
6
  const SKIP_PATTERNS = [
7
7
  /npmjs\.com\/package/,
8
8
  /pypi\.org\/project/,
@@ -13,7 +13,13 @@ const SKIP_PATTERNS = [
13
13
  /badge(s)?\..*\.svg/,
14
14
  /travis-ci\.(org|com)/,
15
15
  /circleci\.com/,
16
- /github\.com\/.*\/actions/ // GitHub Actions badges
16
+ /github\.com\/.*\/actions/, // GitHub Actions badges
17
+ /example\.com/, // placeholder domain
18
+ /example\.org/, // placeholder domain
19
+ /localhost/, // local dev URLs
20
+ /127\.0\.0\.1/, // loopback address
21
+ /\[.*\]/, // template placeholders (e.g., issues/[NUMBER])
22
+ /github\.com\/user\/repo/ // common placeholder in docs
17
23
  ];
18
24
  /**
19
25
  * Parse README content and extract external references
@@ -1 +1 @@
1
- {"version":3,"file":"readme.js","sourceRoot":"","sources":["../../src/parsers/readme.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"readme.js","sourceRoot":"","sources":["../../src/parsers/readme.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,11 @@
1
1
  {
2
2
  "name": "@dependabit/detector",
3
- "version": "0.1.1",
3
+ "version": "0.1.14",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/pradeepmouli/dependabit",
7
+ "directory": "packages/detector"
8
+ },
4
9
  "description": "LLM-based dependency detection for external resources",
5
10
  "type": "module",
6
11
  "main": "dist/index.js",
@@ -13,12 +18,13 @@
13
18
  },
14
19
  "dependencies": {
15
20
  "@actions/core": "^3.0.0",
21
+ "ignore": "^7.0.5",
16
22
  "zod": "^4.3.6",
17
- "@dependabit/github-client": "0.1.1",
18
- "@dependabit/manifest": "0.1.1"
23
+ "@dependabit/github-client": "0.1.13",
24
+ "@dependabit/manifest": "0.1.13"
19
25
  },
20
26
  "devDependencies": {
21
- "@types/node": "^25.2.2",
27
+ "@types/node": "^25.2.3",
22
28
  "tsx": "^4.21.0",
23
29
  "typescript": "^5.9.3",
24
30
  "vitest": "^4.0.18"
package/src/detector.ts CHANGED
@@ -4,8 +4,11 @@
4
4
  */
5
5
 
6
6
  import { readdir, readFile } from 'node:fs/promises';
7
- import { join, relative, resolve, normalize, sep } from 'node:path';
7
+ import { execSync } from 'node:child_process';
8
+ import { homedir } from 'node:os';
9
+ import { dirname, join, relative, resolve, normalize, sep } from 'node:path';
8
10
  import { randomUUID } from 'node:crypto';
11
+ import ignore, { type Ignore } from 'ignore';
9
12
  import type { LLMProvider } from './llm/client.js';
10
13
  import { createClassificationPrompt } from './llm/prompts.js';
11
14
  import { parseReadme } from './parsers/readme.js';
@@ -27,6 +30,9 @@ export interface DetectorOptions {
27
30
  repoPath: string;
28
31
  llmProvider: LLMProvider;
29
32
  ignorePatterns?: string[];
33
+ useGitExcludes?: boolean;
34
+ repoOwner?: string;
35
+ repoName?: string;
30
36
  }
31
37
 
32
38
  export interface DetectionResult {
@@ -42,17 +48,13 @@ export interface DetectionResult {
42
48
 
43
49
  const DEFAULT_IGNORE_PATTERNS = [
44
50
  'node_modules',
45
- '.git',
46
51
  'dist',
47
52
  'build',
48
53
  'target',
49
54
  'vendor',
50
- '.venv',
51
55
  'venv',
52
56
  '__pycache__',
53
- 'coverage',
54
- '.next',
55
- '.nuxt'
57
+ 'coverage'
56
58
  ];
57
59
 
58
60
  /**
@@ -60,12 +62,27 @@ const DEFAULT_IGNORE_PATTERNS = [
60
62
  */
61
63
  export class Detector {
62
64
  private options: Required<DetectorOptions>;
65
+ private ignoreMatcher: Ignore | null = null;
66
+ private ignoreMatcherLoaded = false;
67
+ private skipUrlPatterns: RegExp[];
63
68
 
64
69
  constructor(options: DetectorOptions) {
65
70
  this.options = {
66
71
  ...options,
67
- ignorePatterns: options.ignorePatterns || DEFAULT_IGNORE_PATTERNS
72
+ ignorePatterns: options.ignorePatterns || DEFAULT_IGNORE_PATTERNS,
73
+ useGitExcludes: options.useGitExcludes ?? true,
74
+ repoOwner: options.repoOwner || '',
75
+ repoName: options.repoName || ''
68
76
  };
77
+
78
+ this.skipUrlPatterns = [
79
+ /example\.com/,
80
+ /example\.org/,
81
+ /localhost/,
82
+ /127\.0\.0\.1/,
83
+ /\[.*\]/, // template placeholders like [NUMBER]
84
+ /github\.com\/user\/repo/ // common placeholder in docs
85
+ ];
69
86
  }
70
87
 
71
88
  /**
@@ -222,6 +239,8 @@ Return as JSON with "dependencies" array.`;
222
239
  const now = new Date().toISOString();
223
240
 
224
241
  for (const [url, data] of allReferences) {
242
+ // Skip entries that will end up with low confidence
243
+ // (entries that can't be typed programmatically and LLM assigns low confidence)
225
244
  // Prepare context for potential LLM use
226
245
  const context = data.contexts
227
246
  .map((c) => `${c.file}${c.line ? `:${c.line}` : ''}: ${c.text}`)
@@ -259,6 +278,11 @@ Return as JSON with "dependencies" array.`;
259
278
  typeConfidence = 0.3;
260
279
  }
261
280
 
281
+ // Skip low-confidence entries
282
+ if (typeConfidence < 0.5) {
283
+ continue;
284
+ }
285
+
262
286
  // Step 5: Try programmatic access method determination
263
287
  let accessMethod: AccessMethod | null = this.determineAccessMethod(url);
264
288
 
@@ -354,6 +378,27 @@ Return as JSON: {"accessMethod": "...", "confidence": 0.0-1.0}`;
354
378
  context: { file: string; line?: number; text: string },
355
379
  detectionMethod: DetectionMethod
356
380
  ): void {
381
+ // Skip URLs that don't start with http:// or https://
382
+ if (!/^https?:\/\//.test(url)) {
383
+ return;
384
+ }
385
+
386
+ // Skip URLs matching skip patterns (placeholders, localhost, etc.)
387
+ if (this.skipUrlPatterns.some((pattern) => pattern.test(url))) {
388
+ return;
389
+ }
390
+
391
+ // Skip self-references (URLs pointing to the repo itself)
392
+ if (this.options.repoOwner && this.options.repoName) {
393
+ const selfPattern = new RegExp(
394
+ `github\\.com[/:]${this.escapeRegExp(this.options.repoOwner)}/${this.escapeRegExp(this.options.repoName)}(?:/|$|#|\\?)`,
395
+ 'i'
396
+ );
397
+ if (selfPattern.test(url)) {
398
+ return;
399
+ }
400
+ }
401
+
357
402
  if (!map.has(url)) {
358
403
  map.set(url, {
359
404
  url,
@@ -364,6 +409,10 @@ Return as JSON: {"accessMethod": "...", "confidence": 0.0-1.0}`;
364
409
  map.get(url)!.contexts.push(context);
365
410
  }
366
411
 
412
+ private escapeRegExp(str: string): string {
413
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
414
+ }
415
+
367
416
  /**
368
417
  * Programmatically determine access method based on URL patterns
369
418
  * Returns null if cannot be determined programmatically
@@ -505,7 +554,7 @@ Return as JSON: {"accessMethod": "...", "confidence": 0.0-1.0}`;
505
554
  for (const entry of entries) {
506
555
  const fullPath = join(dir, entry.name);
507
556
 
508
- if (this.shouldIgnore(entry.name)) {
557
+ if (await this.shouldIgnorePath(fullPath, entry.isDirectory())) {
509
558
  continue;
510
559
  }
511
560
 
@@ -516,7 +565,7 @@ Return as JSON: {"accessMethod": "...", "confidence": 0.0-1.0}`;
516
565
  files.push(fullPath);
517
566
  }
518
567
  }
519
- } catch {
568
+ } catch {
520
569
  // Ignore errors (permission denied, etc.)
521
570
  }
522
571
 
@@ -535,6 +584,202 @@ Return as JSON: {"accessMethod": "...", "confidence": 0.0-1.0}`;
535
584
  return this.options.ignorePatterns.some((pattern) => name.includes(pattern));
536
585
  }
537
586
 
587
+ private async shouldIgnorePath(filePath: string, isDirectory = false): Promise<boolean> {
588
+ if (this.isDotDirectoryPath(filePath)) {
589
+ return true;
590
+ }
591
+
592
+ const segments = normalize(filePath).split(sep);
593
+ if (segments.some((segment) => this.shouldIgnore(segment))) {
594
+ return true;
595
+ }
596
+
597
+ return await this.isGitIgnored(filePath, isDirectory);
598
+ }
599
+
600
+ private isDotDirectoryPath(filePath: string): boolean {
601
+ const segments = normalize(filePath).split(sep);
602
+ return segments.some((segment) => segment.startsWith('.') && segment.length > 1);
603
+ }
604
+
605
+ private isDotDirectoryName(name: string): boolean {
606
+ return name.startsWith('.') && name.length > 1;
607
+ }
608
+
609
+ private async isGitIgnored(filePath: string, isDirectory: boolean): Promise<boolean> {
610
+ if (!this.options.useGitExcludes) {
611
+ return false;
612
+ }
613
+ const matcher = await this.getIgnoreMatcher();
614
+ if (!matcher) {
615
+ return false;
616
+ }
617
+
618
+ const relativePath = this.getRepoRelativePath(filePath);
619
+ if (!relativePath) {
620
+ return false;
621
+ }
622
+
623
+ const normalized = relativePath.split(sep).join('/');
624
+ const testPath = isDirectory ? `${normalized}/` : normalized;
625
+ return matcher.ignores(testPath);
626
+ }
627
+
628
+ private getRepoRelativePath(filePath: string): string | null {
629
+ const repoPath = resolve(normalize(this.options.repoPath));
630
+ const normalizedPath = resolve(normalize(filePath));
631
+
632
+ if (normalizedPath === repoPath) {
633
+ return '';
634
+ }
635
+
636
+ if (normalizedPath.startsWith(repoPath + sep)) {
637
+ return relative(repoPath, normalizedPath);
638
+ }
639
+
640
+ return normalize(filePath);
641
+ }
642
+
643
+ private async getIgnoreMatcher(): Promise<Ignore | null> {
644
+ if (this.ignoreMatcherLoaded) {
645
+ return this.ignoreMatcher;
646
+ }
647
+
648
+ this.ignoreMatcherLoaded = true;
649
+
650
+ if (!this.options.useGitExcludes) {
651
+ this.ignoreMatcher = null;
652
+ return this.ignoreMatcher;
653
+ }
654
+
655
+ try {
656
+ const matcher = ignore();
657
+ const gitignoreFiles = await this.collectGitignoreFiles(this.options.repoPath);
658
+ const extraIgnoreFiles = this.collectExtraIgnoreFiles();
659
+
660
+ for (const filePath of gitignoreFiles) {
661
+ const content = await readFile(filePath, 'utf-8');
662
+ const rules = this.prefixGitignoreRules(filePath, content);
663
+ if (rules.length > 0) {
664
+ matcher.add(rules);
665
+ }
666
+ }
667
+
668
+ for (const filePath of extraIgnoreFiles) {
669
+ try {
670
+ const content = await readFile(filePath, 'utf-8');
671
+ const rules = this.prefixGitignoreRules(filePath, content, '');
672
+ if (rules.length > 0) {
673
+ matcher.add(rules);
674
+ }
675
+ } catch {
676
+ // Ignore missing or unreadable global ignore files
677
+ }
678
+ }
679
+
680
+ this.ignoreMatcher = matcher;
681
+ } catch {
682
+ this.ignoreMatcher = null;
683
+ }
684
+
685
+ return this.ignoreMatcher;
686
+ }
687
+
688
+ private async collectGitignoreFiles(dir: string): Promise<string[]> {
689
+ const files: string[] = [];
690
+
691
+ try {
692
+ const entries = await readdir(dir, { withFileTypes: true });
693
+ for (const entry of entries) {
694
+ if (entry.isDirectory()) {
695
+ if (this.isDotDirectoryName(entry.name) || this.shouldIgnore(entry.name)) {
696
+ continue;
697
+ }
698
+ files.push(...(await this.collectGitignoreFiles(join(dir, entry.name))));
699
+ } else if (entry.isFile() && entry.name === '.gitignore') {
700
+ files.push(join(dir, entry.name));
701
+ }
702
+ }
703
+ } catch {
704
+ // Ignore errors
705
+ }
706
+
707
+ return files;
708
+ }
709
+
710
+ private prefixGitignoreRules(filePath: string, content: string, basePrefix?: string): string[] {
711
+ const repoPath = resolve(normalize(this.options.repoPath));
712
+ const ignoreDir = dirname(filePath);
713
+ const relativeDir = relative(repoPath, ignoreDir).split(sep).join('/');
714
+ const prefix = basePrefix !== undefined ? basePrefix : relativeDir ? `${relativeDir}/` : '';
715
+
716
+ return content
717
+ .split('\n')
718
+ .map((line) => line.trim())
719
+ .filter((line) => line && !line.startsWith('#'))
720
+ .map((line) => {
721
+ const negated = line.startsWith('!');
722
+ const raw = negated ? line.slice(1) : line;
723
+ const trimmed = raw.startsWith('/') ? raw.slice(1) : raw;
724
+ const scoped = `${prefix}${trimmed}`;
725
+ return negated ? `!${scoped}` : scoped;
726
+ });
727
+ }
728
+
729
+ private collectExtraIgnoreFiles(): string[] {
730
+ const files = new Set<string>();
731
+
732
+ files.add(join(this.options.repoPath, '.git', 'info', 'exclude'));
733
+
734
+ const globalConfig = this.getGlobalExcludeFileFromGit();
735
+ if (globalConfig) {
736
+ files.add(globalConfig);
737
+ }
738
+
739
+ for (const fallback of this.getDefaultGlobalExcludeFiles()) {
740
+ files.add(fallback);
741
+ }
742
+
743
+ return Array.from(files);
744
+ }
745
+
746
+ private getGlobalExcludeFileFromGit(): string | null {
747
+ try {
748
+ const output = execSync('git config --get core.excludesfile', {
749
+ stdio: ['ignore', 'pipe', 'ignore']
750
+ })
751
+ .toString()
752
+ .trim();
753
+
754
+ if (!output) {
755
+ return null;
756
+ }
757
+
758
+ return this.expandHomePath(output);
759
+ } catch {
760
+ return null;
761
+ }
762
+ }
763
+
764
+ private getDefaultGlobalExcludeFiles(): string[] {
765
+ const home = homedir();
766
+ return [
767
+ join(home, '.config', 'git', 'ignore'),
768
+ join(home, '.gitignore_global'),
769
+ join(home, '.gitignore')
770
+ ];
771
+ }
772
+
773
+ private expandHomePath(filePath: string): string {
774
+ if (filePath.startsWith('~/')) {
775
+ return join(homedir(), filePath.slice(2));
776
+ }
777
+ if (filePath === '~') {
778
+ return homedir();
779
+ }
780
+ return filePath;
781
+ }
782
+
538
783
  /**
539
784
  * Analyze only specific files for dependencies (for incremental updates)
540
785
  * This is more efficient than full repository scan when only few files changed
@@ -555,6 +800,9 @@ Return as JSON: {"accessMethod": "...", "confidence": 0.0-1.0}`;
555
800
  let totalLatencyMs = 0;
556
801
 
557
802
  for (const filePath of filePaths) {
803
+ if (await this.shouldIgnorePath(filePath)) {
804
+ continue;
805
+ }
558
806
  // Validate that the file path is safe before joining
559
807
  const normalizedRepoPath = resolve(normalize(this.options.repoPath));
560
808
  const normalizedFilePath = normalize(filePath);
@@ -3,7 +3,7 @@
3
3
  * Integrates with GitHub Copilot via CLI commands
4
4
  */
5
5
 
6
- import { exec } from 'node:child_process';
6
+ import { execFile } from 'node:child_process';
7
7
  import { promisify } from 'node:util';
8
8
  import type {
9
9
  LLMProvider,
@@ -15,7 +15,7 @@ import type {
15
15
  } from './client.js';
16
16
  import { SYSTEM_PROMPT } from './prompts.js';
17
17
 
18
- const execAsync = promisify(exec);
18
+ const execFileAsync = promisify(execFile);
19
19
 
20
20
  export class GitHubCopilotProvider implements LLMProvider {
21
21
  private config: Required<LLMProviderConfig>;
@@ -44,14 +44,17 @@ export class GitHubCopilotProvider implements LLMProvider {
44
44
  // Combine system prompt and user prompt for CLI
45
45
  const fullPrompt = `${SYSTEM_PROMPT}\n\n${prompt}`;
46
46
 
47
- // Escape the prompt for shell safety (basic escaping)
48
- const escapedPrompt = fullPrompt.replace(/"/g, '\\"').replace(/\$/g, '\\$');
49
-
50
- // Use gh copilot suggest command to get AI response
51
- // The --yes flag auto-accepts the suggestion, --shell-out returns raw output
52
- const command = `echo "${escapedPrompt}" | gh copilot suggest --yes 2>&1`;
53
-
54
- const { stdout, stderr } = await execAsync(command, {
47
+ // Use execFile to avoid shell escaping issues and command injection
48
+ // Pass prompt directly as an argument without manual escaping
49
+ const args = [
50
+ 'copilot',
51
+ '-p',
52
+ fullPrompt,
53
+ '--silent',
54
+ '--allow-all-tools'
55
+ ];
56
+
57
+ const { stdout, stderr } = await execFileAsync('gh', args, {
55
58
  maxBuffer: 10 * 1024 * 1024, // 10MB buffer for large responses
56
59
  timeout: 60000 // 60 second timeout
57
60
  });
@@ -17,11 +17,20 @@ INCLUDE these types of dependencies:
17
17
 
18
18
  EXCLUDE these (handled by dependabot):
19
19
  - NPM packages in package.json
20
- - Python packages in requirements.txt
20
+ - Python packages in requirements.txt
21
21
  - Rust crates in Cargo.toml
22
22
  - Docker images in Dockerfile
23
23
  - Any declared package manager dependencies
24
24
 
25
+ ALSO EXCLUDE (false positives):
26
+ - URLs that reference the repository itself (self-references)
27
+ - Relative file paths (e.g., CONTRIBUTING.md, docs/guide.md, ./src/utils)
28
+ - Placeholder URLs used in documentation examples (example.com, example.org, localhost)
29
+ - Internal documentation links within the same repository
30
+ - URLs with template variables or placeholders (e.g., issues/[NUMBER], user/repo)
31
+
32
+ Only return dependencies with confidence >= 0.7.
33
+
25
34
  For each dependency found, provide:
26
35
  1. url: The complete URL
27
36
  2. name: A descriptive name
@@ -10,7 +10,7 @@ export interface ExtractedReference {
10
10
  type: 'markdown-link' | 'bare-url' | 'reference-link';
11
11
  }
12
12
 
13
- // Patterns to skip (package managers, CI badges, shields.io)
13
+ // Patterns to skip (package managers, CI badges, shields.io, placeholders)
14
14
  const SKIP_PATTERNS = [
15
15
  /npmjs\.com\/package/,
16
16
  /pypi\.org\/project/,
@@ -21,7 +21,13 @@ const SKIP_PATTERNS = [
21
21
  /badge(s)?\..*\.svg/,
22
22
  /travis-ci\.(org|com)/,
23
23
  /circleci\.com/,
24
- /github\.com\/.*\/actions/ // GitHub Actions badges
24
+ /github\.com\/.*\/actions/, // GitHub Actions badges
25
+ /example\.com/, // placeholder domain
26
+ /example\.org/, // placeholder domain
27
+ /localhost/, // local dev URLs
28
+ /127\.0\.0\.1/, // loopback address
29
+ /\[.*\]/, // template placeholders (e.g., issues/[NUMBER])
30
+ /github\.com\/user\/repo/ // common placeholder in docs
25
31
  ];
26
32
 
27
33
  /**