bugproof 0.1.2 → 0.2.5

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 (78) hide show
  1. package/CHANGELOG.md +61 -5
  2. package/README.md +232 -8
  3. package/bin/bugproof.cmd +2 -0
  4. package/dist/capture/env-snapshot.d.ts +53 -0
  5. package/dist/capture/env-snapshot.d.ts.map +1 -0
  6. package/dist/capture/env-snapshot.js +122 -0
  7. package/dist/capture/env-snapshot.js.map +1 -0
  8. package/dist/capture/language-support.d.ts +55 -0
  9. package/dist/capture/language-support.d.ts.map +1 -0
  10. package/dist/capture/language-support.js +505 -0
  11. package/dist/capture/language-support.js.map +1 -0
  12. package/dist/capture/packager.d.ts +9 -0
  13. package/dist/capture/packager.d.ts.map +1 -1
  14. package/dist/capture/packager.js +23 -2
  15. package/dist/capture/packager.js.map +1 -1
  16. package/dist/capture/source-strategy.d.ts +52 -0
  17. package/dist/capture/source-strategy.d.ts.map +1 -0
  18. package/dist/capture/source-strategy.js +227 -0
  19. package/dist/capture/source-strategy.js.map +1 -0
  20. package/dist/cli.js +373 -12
  21. package/dist/cli.js.map +1 -1
  22. package/dist/config/loader.d.ts +44 -0
  23. package/dist/config/loader.d.ts.map +1 -0
  24. package/dist/config/loader.js +87 -0
  25. package/dist/config/loader.js.map +1 -0
  26. package/dist/replay/engine.d.ts +9 -0
  27. package/dist/replay/engine.d.ts.map +1 -1
  28. package/dist/replay/engine.js +29 -3
  29. package/dist/replay/engine.js.map +1 -1
  30. package/dist/replay/hints.d.ts +18 -0
  31. package/dist/replay/hints.d.ts.map +1 -0
  32. package/dist/replay/hints.js +138 -0
  33. package/dist/replay/hints.js.map +1 -0
  34. package/dist/replay/sandbox.js +41 -14
  35. package/dist/replay/sandbox.js.map +1 -1
  36. package/dist/replay/verdict.d.ts.map +1 -1
  37. package/dist/replay/verdict.js +41 -5
  38. package/dist/replay/verdict.js.map +1 -1
  39. package/dist/sandbox/bugbox.d.ts.map +1 -1
  40. package/dist/sandbox/bugbox.js +40 -6
  41. package/dist/sandbox/bugbox.js.map +1 -1
  42. package/dist/sandbox/container.d.ts +81 -0
  43. package/dist/sandbox/container.d.ts.map +1 -0
  44. package/dist/sandbox/container.js +343 -0
  45. package/dist/sandbox/container.js.map +1 -0
  46. package/dist/sandbox/cross-platform.d.ts +59 -0
  47. package/dist/sandbox/cross-platform.d.ts.map +1 -0
  48. package/dist/sandbox/cross-platform.js +330 -0
  49. package/dist/sandbox/cross-platform.js.map +1 -0
  50. package/dist/sandbox/filesystem.d.ts +2 -2
  51. package/dist/sandbox/filesystem.d.ts.map +1 -1
  52. package/dist/sandbox/filesystem.js +46 -19
  53. package/dist/sandbox/filesystem.js.map +1 -1
  54. package/dist/sandbox/network.d.ts.map +1 -1
  55. package/dist/sandbox/network.js +31 -2
  56. package/dist/sandbox/network.js.map +1 -1
  57. package/dist/share/gist.d.ts +21 -0
  58. package/dist/share/gist.d.ts.map +1 -0
  59. package/dist/share/gist.js +158 -0
  60. package/dist/share/gist.js.map +1 -0
  61. package/dist/utils/archive.d.ts +1 -0
  62. package/dist/utils/archive.d.ts.map +1 -1
  63. package/dist/utils/archive.js +42 -1
  64. package/dist/utils/archive.js.map +1 -1
  65. package/dist/utils/artifact-validation.d.ts +7 -0
  66. package/dist/utils/artifact-validation.d.ts.map +1 -0
  67. package/dist/utils/artifact-validation.js +212 -0
  68. package/dist/utils/artifact-validation.js.map +1 -0
  69. package/dist/utils/dependencies.d.ts +18 -0
  70. package/dist/utils/dependencies.d.ts.map +1 -0
  71. package/dist/utils/dependencies.js +218 -0
  72. package/dist/utils/dependencies.js.map +1 -0
  73. package/dist/utils/ui.d.ts +1 -0
  74. package/dist/utils/ui.d.ts.map +1 -1
  75. package/dist/utils/ui.js +1 -0
  76. package/dist/utils/ui.js.map +1 -1
  77. package/package.json +5 -2
  78. package/scripts/postinstall.cjs +38 -5
@@ -0,0 +1,218 @@
1
+ /**
2
+ * Dependency Detection Engine
3
+ *
4
+ * Analyzes stderr output to detect missing dependencies and suggest
5
+ * installation commands. Works across Node.js, Python, Ruby, Go, Rust, and more.
6
+ */
7
+ const DETECTION_RULES = [
8
+ // Node.js / npm
9
+ {
10
+ pattern: /Cannot find module ['"]([^'"]+)['"]/g,
11
+ language: 'node',
12
+ extractName: (m) => {
13
+ const mod = m[1];
14
+ if (mod.startsWith('.') || mod.startsWith('/'))
15
+ return '';
16
+ // Handle scoped packages: @scope/name
17
+ if (mod.startsWith('@')) {
18
+ const parts = mod.split('/');
19
+ return parts.length >= 2 ? `${parts[0]}/${parts[1]}` : parts[0];
20
+ }
21
+ return mod.split('/')[0];
22
+ },
23
+ installCommand: (name) => `npm install ${name}`,
24
+ confidence: 'high',
25
+ },
26
+ {
27
+ pattern: /Error \[ERR_MODULE_NOT_FOUND\]: Cannot find package '([^']+)'/g,
28
+ language: 'node',
29
+ extractName: (m) => m[1],
30
+ installCommand: (name) => `npm install ${name}`,
31
+ confidence: 'high',
32
+ },
33
+ // Python
34
+ {
35
+ pattern: /ModuleNotFoundError: No module named '([^']+)'/g,
36
+ language: 'python',
37
+ extractName: (m) => m[1].split('.')[0],
38
+ installCommand: (name) => `pip install ${name}`,
39
+ confidence: 'high',
40
+ },
41
+ {
42
+ pattern: /ImportError: No module named (\S+)/g,
43
+ language: 'python',
44
+ extractName: (m) => m[1].split('.')[0],
45
+ installCommand: (name) => `pip install ${name}`,
46
+ confidence: 'high',
47
+ },
48
+ // Ruby
49
+ {
50
+ pattern: /cannot load such file -- ([^\s(]+)/g,
51
+ language: 'ruby',
52
+ extractName: (m) => m[1],
53
+ installCommand: (name) => `gem install ${name}`,
54
+ confidence: 'medium',
55
+ },
56
+ {
57
+ pattern: /Could not find gem '([^']+)'/g,
58
+ language: 'ruby',
59
+ extractName: (m) => m[1].split(' ')[0],
60
+ installCommand: (name) => `gem install ${name}`,
61
+ confidence: 'high',
62
+ },
63
+ // Go
64
+ {
65
+ pattern: /cannot find package "([^"]+)"/g,
66
+ language: 'go',
67
+ extractName: (m) => m[1],
68
+ installCommand: (name) => `go get ${name}`,
69
+ confidence: 'high',
70
+ },
71
+ // Rust / Cargo
72
+ {
73
+ pattern: /error\[E0433\]: failed to resolve:.*`([^`]+)`/g,
74
+ language: 'rust',
75
+ extractName: (m) => m[1],
76
+ installCommand: (name) => `cargo add ${name}`,
77
+ confidence: 'medium',
78
+ },
79
+ // Java — ClassNotFoundException
80
+ {
81
+ pattern: /ClassNotFoundException:\s+([\w.]+)/g,
82
+ language: 'java',
83
+ extractName: (m) => m[1],
84
+ installCommand: (name) => `# Add '${name}' to classpath or pom.xml/build.gradle`,
85
+ confidence: 'high',
86
+ },
87
+ // Java — NoClassDefFoundError
88
+ {
89
+ pattern: /NoClassDefFoundError:\s+([\w/$]+)/g,
90
+ language: 'java',
91
+ extractName: (m) => m[1].replace(/\//g, '.').replace(/\$$/, ''),
92
+ installCommand: (name) => `# Missing class: ${name}. Check dependencies and classpath.`,
93
+ confidence: 'high',
94
+ },
95
+ // Java/Maven — dependency resolution failure
96
+ {
97
+ pattern: /Could not find artifact ([\w.:-]+)/g,
98
+ language: 'java',
99
+ extractName: (m) => m[1],
100
+ installCommand: (name) => `# Maven: add <dependency> for ${name} to pom.xml`,
101
+ confidence: 'high',
102
+ },
103
+ // Java/Gradle — dependency not found
104
+ {
105
+ pattern: /Could not resolve (?:all )?(?:dependencies|artifacts).*?>([\w.:-]+)/g,
106
+ language: 'java',
107
+ extractName: (m) => m[1],
108
+ installCommand: (name) => `# Gradle: add implementation("${name}") to build.gradle`,
109
+ confidence: 'medium',
110
+ },
111
+ // C/C++ — missing header
112
+ {
113
+ pattern: /fatal error:\s+([^\s:]+\.h):\s*No such file/g,
114
+ language: 'cpp',
115
+ extractName: (m) => m[1],
116
+ installCommand: (name) => `# Install dev package for ${name}. Try: apt install lib*-dev`,
117
+ confidence: 'high',
118
+ },
119
+ // C/C++ — undefined reference (linker)
120
+ {
121
+ pattern: /undefined reference to [`']([^'`]+)[`']/g,
122
+ language: 'cpp',
123
+ extractName: (m) => m[1],
124
+ installCommand: (name) => `# Linker: missing symbol '${name}'. Add the library with -l flag.`,
125
+ confidence: 'medium',
126
+ },
127
+ // C/C++ — cannot find -l (linker library)
128
+ {
129
+ pattern: /cannot find -l(\w+)/g,
130
+ language: 'cpp',
131
+ extractName: (m) => m[1],
132
+ installCommand: (name) => `apt install lib${name}-dev # (Debian/Ubuntu)`,
133
+ confidence: 'high',
134
+ },
135
+ // .NET — package not found
136
+ {
137
+ pattern: /error NU1101: Unable to find package (\S+)/g,
138
+ language: 'dotnet',
139
+ extractName: (m) => m[1],
140
+ installCommand: (name) => `dotnet add package ${name}`,
141
+ confidence: 'high',
142
+ },
143
+ // .NET — assembly not found
144
+ {
145
+ pattern: /Could not load file or assembly '([^']+)'/g,
146
+ language: 'dotnet',
147
+ extractName: (m) => m[1].split(',')[0],
148
+ installCommand: (name) => `dotnet add package ${name}`,
149
+ confidence: 'medium',
150
+ },
151
+ // Kotlin — unresolved reference
152
+ {
153
+ pattern: /Unresolved reference: (\w+)/g,
154
+ language: 'kotlin',
155
+ extractName: (m) => m[1],
156
+ installCommand: (name) => `# Kotlin: add dependency for '${name}' to build.gradle.kts`,
157
+ confidence: 'medium',
158
+ },
159
+ // System libraries
160
+ {
161
+ pattern: /error while loading shared libraries: lib([^.]+)\.so/g,
162
+ language: 'system',
163
+ extractName: (m) => m[1],
164
+ installCommand: (name) => `apt install lib${name}-dev # (Debian/Ubuntu)`,
165
+ confidence: 'medium',
166
+ },
167
+ // Windows DLL not found
168
+ {
169
+ pattern: /The specified module could not be found.*?(\w+\.dll)/gi,
170
+ language: 'system',
171
+ extractName: (m) => m[1],
172
+ installCommand: (name) => `# Missing DLL: ${name}. Install the required runtime or library.`,
173
+ confidence: 'medium',
174
+ },
175
+ // macOS — dylib not found
176
+ {
177
+ pattern: /Library not loaded:\s+.*?lib(\w+)\.dylib/g,
178
+ language: 'system',
179
+ extractName: (m) => m[1],
180
+ installCommand: (name) => `brew install ${name} # (macOS via Homebrew)`,
181
+ confidence: 'medium',
182
+ },
183
+ // Generic "command not found"
184
+ {
185
+ pattern: /(?:command not found|not recognized as .* command)[:\s]+['"]?(\S+)/gi,
186
+ language: 'system',
187
+ extractName: (m) => m[1].replace(/['"]/g, ''),
188
+ installCommand: (name) => `# Install '${name}' — check your package manager`,
189
+ confidence: 'medium',
190
+ },
191
+ ];
192
+ /**
193
+ * Scans stderr output and detects missing dependencies.
194
+ * Returns a deduplicated list of dependencies with install commands.
195
+ */
196
+ export function detectMissingDependencies(stderr) {
197
+ const seen = new Set();
198
+ const deps = [];
199
+ for (const rule of DETECTION_RULES) {
200
+ // Reset regex lastIndex for global patterns
201
+ rule.pattern.lastIndex = 0;
202
+ let match;
203
+ while ((match = rule.pattern.exec(stderr)) !== null) {
204
+ const name = rule.extractName(match);
205
+ if (!name || seen.has(`${rule.language}:${name}`))
206
+ continue;
207
+ seen.add(`${rule.language}:${name}`);
208
+ deps.push({
209
+ name,
210
+ language: rule.language,
211
+ installCommand: rule.installCommand(name),
212
+ confidence: rule.confidence,
213
+ });
214
+ }
215
+ }
216
+ return deps;
217
+ }
218
+ //# sourceMappingURL=dependencies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../../src/utils/dependencies.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Colored terminal output for BugProof CLI.
3
3
  * Uses ANSI codes directly so we avoid ESM-only import issues with chalk v5.
4
+ * Supports structured logging for CI/CD pipelines.
4
5
  */
5
6
  export declare const c: {
6
7
  bold: (t: string) => string;
@@ -1 +1 @@
1
- {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../src/utils/ui.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,eAAO,MAAM,CAAC;cACC,MAAM;aACN,MAAM;aACN,MAAM;eACN,MAAM;gBACN,MAAM;cACN,MAAM;iBACN,MAAM;cACN,MAAM;cACN,MAAM;CACpB,CAAC;AAEF,eAAO,MAAM,KAAK;;;;;;;;CAQjB,CAAC;AAEF,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAOzC;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEzC;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEtC;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEvC;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEtC;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAEvD"}
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../src/utils/ui.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,eAAO,MAAM,CAAC;cACC,MAAM;aACN,MAAM;aACN,MAAM;eACN,MAAM;gBACN,MAAM;cACN,MAAM;iBACN,MAAM;cACN,MAAM;cACN,MAAM;CACpB,CAAC;AAEF,eAAO,MAAM,KAAK;;;;;;;;CAQjB,CAAC;AAEF,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAOzC;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEzC;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEtC;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEvC;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEtC;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAEvD"}
package/dist/utils/ui.js CHANGED
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Colored terminal output for BugProof CLI.
3
3
  * Uses ANSI codes directly so we avoid ESM-only import issues with chalk v5.
4
+ * Supports structured logging for CI/CD pipelines.
4
5
  */
5
6
  const isColorSupported = process.stdout.isTTY && !process.env['NO_COLOR'];
6
7
  function wrap(code, resetCode, text) {
@@ -1 +1 @@
1
- {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/utils/ui.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/utils/ui.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;AAE1E,SAAS,IAAI,CAAC,IAAY,EAAE,SAAiB,EAAE,IAAY;IACzD,IAAI,CAAC,gBAAgB;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,QAAQ,IAAI,IAAI,IAAI,QAAQ,SAAS,GAAG,CAAC;AAClD,CAAC;AAED,MAAM,CAAC,MAAM,CAAC,GAAG;IACf,IAAI,EAAK,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACtC,GAAG,EAAM,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACtC,GAAG,EAAM,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACvC,KAAK,EAAI,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACvC,MAAM,EAAG,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACvC,IAAI,EAAK,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACvC,OAAO,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACvC,IAAI,EAAK,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACvC,IAAI,EAAK,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;CACxC,CAAC;AAEF,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,KAAK,EAAI,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG;IAC1C,KAAK,EAAI,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG;IAC1C,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG;IAC1C,KAAK,EAAI,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,gBAAgB;IAC5D,GAAG,EAAM,gBAAgB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,EAAE,+BAA+B;IACjF,GAAG,EAAM,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG;IAC1C,GAAG,EAAM,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG;CAC3C,CAAC;AAEF,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,IAAI,QAAQ,CAAC,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,IAAI,QAAQ,CAAC,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,GAAW;IAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,GAAW;IAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,GAAW;IAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,GAAW,EAAE,KAAa;IAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC;AACrD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bugproof",
3
- "version": "0.1.2",
3
+ "version": "0.2.5",
4
4
  "description": "Executable bug artifacts — portable, reproducible bug reports",
5
5
  "main": "dist/cli.js",
6
6
  "type": "module",
@@ -8,17 +8,19 @@
8
8
  "bugproof": "dist/cli.js"
9
9
  },
10
10
  "scripts": {
11
+ "prepare": "npm run build",
11
12
  "build": "tsc",
12
13
  "postinstall": "node scripts/postinstall.cjs",
13
14
  "prepublishOnly": "npm run build && npm run test && npm run lint",
14
15
  "dev": "tsx watch src/index.ts",
15
- "test": "jest",
16
+ "test": "npm run build && jest",
16
17
  "test:watch": "jest --watch",
17
18
  "test:coverage": "jest --coverage",
18
19
  "lint": "eslint src --ext .ts",
19
20
  "format": "prettier --write 'src/**/*.ts'",
20
21
  "cli": "tsx src/cli.ts",
21
22
  "test:e2e": "node scripts/e2e-matrix.js",
23
+ "test:matrix": "node scripts/multi-language-matrix.cjs",
22
24
  "test:comprehensive": "node scripts/comprehensive-test.js",
23
25
  "release": "node scripts/release.cjs"
24
26
  },
@@ -58,6 +60,7 @@
58
60
  },
59
61
  "files": [
60
62
  "dist",
63
+ "bin",
61
64
  "assets",
62
65
  "scripts/bugproof-file-association-*.sh",
63
66
  "scripts/bugproof-file-association-*.reg",
@@ -17,11 +17,11 @@ function isCommandAvailable(command) {
17
17
  return result.status === 0;
18
18
  }
19
19
 
20
- function runCommand(command, args, timeout = 5000) {
20
+ function runCommand(command, args, timeout = 5000, captureOutput = false) {
21
21
  return spawnSync(command, args, {
22
22
  encoding: 'utf8',
23
23
  timeout,
24
- stdio: 'ignore',
24
+ stdio: captureOutput ? 'pipe' : 'ignore',
25
25
  });
26
26
  }
27
27
 
@@ -56,6 +56,27 @@ function ensureParentDir(filePath) {
56
56
  fs.mkdirSync(path.dirname(filePath), { recursive: true });
57
57
  }
58
58
 
59
+ function isSafeWindowsPath(value) {
60
+ return typeof value === 'string'
61
+ && value.length > 0
62
+ && !/[\r\n\0]/.test(value);
63
+ }
64
+
65
+ function quoteForWindowsCommand(value) {
66
+ if (!isSafeWindowsPath(value)) {
67
+ throw new Error('Unsafe Windows path detected for registry command.');
68
+ }
69
+ return `"${value.replace(/"/g, '\\"')}"`;
70
+ }
71
+
72
+ function queryRegistryValue(keyPath) {
73
+ const result = runCommand('reg', ['query', keyPath, '/ve'], 5000, true);
74
+ if (result.status !== 0) {
75
+ return null;
76
+ }
77
+ return result.stdout || '';
78
+ }
79
+
59
80
  function registerWindowsAssociation() {
60
81
  if (process.platform !== 'win32') {
61
82
  return;
@@ -63,7 +84,7 @@ function registerWindowsAssociation() {
63
84
 
64
85
  const reg = (args) => runCommand('reg', args, 5000);
65
86
 
66
- const openCommand = `\"${process.execPath}\" \"${cliPath}\" replay \"%1\"`;
87
+ const openCommand = `${quoteForWindowsCommand(process.execPath)} ${quoteForWindowsCommand(cliPath)} replay \"%1\"`;
67
88
 
68
89
  const outcomes = [];
69
90
 
@@ -77,7 +98,7 @@ function registerWindowsAssociation() {
77
98
  '/f',
78
99
  ]));
79
100
 
80
- if (fs.existsSync(iconPath)) {
101
+ if (fs.existsSync(iconPath) && isSafeWindowsPath(iconPath)) {
81
102
  outcomes.push(reg([
82
103
  'add',
83
104
  'HKCU\\Software\\Classes\\BugProof.Artifact\\DefaultIcon',
@@ -101,6 +122,11 @@ function registerWindowsAssociation() {
101
122
  if (failed) {
102
123
  log('WARNING: Windows .bug association setup partially failed. Run scripts/bugproof-file-association-windows.reg manually.');
103
124
  } else {
125
+ const commandQuery = queryRegistryValue('HKCU\\Software\\Classes\\BugProof.Artifact\\shell\\open\\command');
126
+ if (!commandQuery || !commandQuery.includes(openCommand)) {
127
+ log('WARNING: Windows association write could not be verified. Run scripts/bugproof-file-association-windows.reg manually.');
128
+ return;
129
+ }
104
130
  log('Windows .bug file association registered (HKCU).');
105
131
  }
106
132
  }
@@ -212,4 +238,11 @@ function main() {
212
238
  }
213
239
  }
214
240
 
215
- main();
241
+ if (require.main === module) {
242
+ main();
243
+ }
244
+
245
+ module.exports = {
246
+ isSafeWindowsPath,
247
+ quoteForWindowsCommand,
248
+ };