bugproof 0.1.1

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 (110) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/README.md +256 -0
  3. package/assets/icon-16x16.png +0 -0
  4. package/assets/icon-32x32.png +0 -0
  5. package/assets/icon-512x512.png +0 -0
  6. package/dist/capture/engine.d.ts +12 -0
  7. package/dist/capture/engine.d.ts.map +1 -0
  8. package/dist/capture/engine.js +129 -0
  9. package/dist/capture/engine.js.map +1 -0
  10. package/dist/capture/packager.d.ts +39 -0
  11. package/dist/capture/packager.d.ts.map +1 -0
  12. package/dist/capture/packager.js +145 -0
  13. package/dist/capture/packager.js.map +1 -0
  14. package/dist/cli.d.ts +3 -0
  15. package/dist/cli.d.ts.map +1 -0
  16. package/dist/cli.js +538 -0
  17. package/dist/cli.js.map +1 -0
  18. package/dist/diff/engine.d.ts +28 -0
  19. package/dist/diff/engine.d.ts.map +1 -0
  20. package/dist/diff/engine.js +88 -0
  21. package/dist/diff/engine.js.map +1 -0
  22. package/dist/replay/engine.d.ts +41 -0
  23. package/dist/replay/engine.d.ts.map +1 -0
  24. package/dist/replay/engine.js +69 -0
  25. package/dist/replay/engine.js.map +1 -0
  26. package/dist/replay/sandbox.d.ts +33 -0
  27. package/dist/replay/sandbox.d.ts.map +1 -0
  28. package/dist/replay/sandbox.js +167 -0
  29. package/dist/replay/sandbox.js.map +1 -0
  30. package/dist/replay/verdict.d.ts +8 -0
  31. package/dist/replay/verdict.d.ts.map +1 -0
  32. package/dist/replay/verdict.js +32 -0
  33. package/dist/replay/verdict.js.map +1 -0
  34. package/dist/sandbox/bugbox.d.ts +38 -0
  35. package/dist/sandbox/bugbox.d.ts.map +1 -0
  36. package/dist/sandbox/bugbox.js +122 -0
  37. package/dist/sandbox/bugbox.js.map +1 -0
  38. package/dist/sandbox/capabilities.d.ts +33 -0
  39. package/dist/sandbox/capabilities.d.ts.map +1 -0
  40. package/dist/sandbox/capabilities.js +53 -0
  41. package/dist/sandbox/capabilities.js.map +1 -0
  42. package/dist/sandbox/filesystem.d.ts +50 -0
  43. package/dist/sandbox/filesystem.d.ts.map +1 -0
  44. package/dist/sandbox/filesystem.js +134 -0
  45. package/dist/sandbox/filesystem.js.map +1 -0
  46. package/dist/sandbox/network.d.ts +68 -0
  47. package/dist/sandbox/network.d.ts.map +1 -0
  48. package/dist/sandbox/network.js +136 -0
  49. package/dist/sandbox/network.js.map +1 -0
  50. package/dist/sandbox/process.d.ts +17 -0
  51. package/dist/sandbox/process.d.ts.map +1 -0
  52. package/dist/sandbox/process.js +30 -0
  53. package/dist/sandbox/process.js.map +1 -0
  54. package/dist/sandbox/resources.d.ts +21 -0
  55. package/dist/sandbox/resources.d.ts.map +1 -0
  56. package/dist/sandbox/resources.js +60 -0
  57. package/dist/sandbox/resources.js.map +1 -0
  58. package/dist/types/artifact.d.ts +57 -0
  59. package/dist/types/artifact.d.ts.map +1 -0
  60. package/dist/types/artifact.js +2 -0
  61. package/dist/types/artifact.js.map +1 -0
  62. package/dist/types/failure.d.ts +12 -0
  63. package/dist/types/failure.d.ts.map +1 -0
  64. package/dist/types/failure.js +2 -0
  65. package/dist/types/failure.js.map +1 -0
  66. package/dist/utils/archive.d.ts +13 -0
  67. package/dist/utils/archive.d.ts.map +1 -0
  68. package/dist/utils/archive.js +39 -0
  69. package/dist/utils/archive.js.map +1 -0
  70. package/dist/utils/associations.d.ts +10 -0
  71. package/dist/utils/associations.d.ts.map +1 -0
  72. package/dist/utils/associations.js +46 -0
  73. package/dist/utils/associations.js.map +1 -0
  74. package/dist/utils/exclude.d.ts +12 -0
  75. package/dist/utils/exclude.d.ts.map +1 -0
  76. package/dist/utils/exclude.js +42 -0
  77. package/dist/utils/exclude.js.map +1 -0
  78. package/dist/utils/fingerprint.d.ts +16 -0
  79. package/dist/utils/fingerprint.d.ts.map +1 -0
  80. package/dist/utils/fingerprint.js +72 -0
  81. package/dist/utils/fingerprint.js.map +1 -0
  82. package/dist/utils/git.d.ts +13 -0
  83. package/dist/utils/git.d.ts.map +1 -0
  84. package/dist/utils/git.js +41 -0
  85. package/dist/utils/git.js.map +1 -0
  86. package/dist/utils/json-output.d.ts +36 -0
  87. package/dist/utils/json-output.d.ts.map +1 -0
  88. package/dist/utils/json-output.js +49 -0
  89. package/dist/utils/json-output.js.map +1 -0
  90. package/dist/utils/paths.d.ts +19 -0
  91. package/dist/utils/paths.d.ts.map +1 -0
  92. package/dist/utils/paths.js +43 -0
  93. package/dist/utils/paths.js.map +1 -0
  94. package/dist/utils/secrets.d.ts +13 -0
  95. package/dist/utils/secrets.d.ts.map +1 -0
  96. package/dist/utils/secrets.js +52 -0
  97. package/dist/utils/secrets.js.map +1 -0
  98. package/dist/utils/security.d.ts +27 -0
  99. package/dist/utils/security.d.ts.map +1 -0
  100. package/dist/utils/security.js +75 -0
  101. package/dist/utils/security.js.map +1 -0
  102. package/dist/utils/ui.d.ts +31 -0
  103. package/dist/utils/ui.d.ts.map +1 -0
  104. package/dist/utils/ui.js +54 -0
  105. package/dist/utils/ui.js.map +1 -0
  106. package/package.json +80 -0
  107. package/scripts/bugproof-file-association-linux.sh +80 -0
  108. package/scripts/bugproof-file-association-macos.sh +48 -0
  109. package/scripts/bugproof-file-association-windows.reg +44 -0
  110. package/scripts/postinstall.cjs +215 -0
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Normalizes a path to consistently use forward slashes (/) across all platforms.
3
+ * This ensures artifact portability between Windows, Linux, and macOS.
4
+ */
5
+ export declare function normalizeArtifactPath(p: string): string;
6
+ /**
7
+ * Converts a portable artifact path back to the platform-specific path separator.
8
+ * Useful during replay on a host machine.
9
+ */
10
+ export declare function toPlatformPath(artifactPath: string): string;
11
+ /**
12
+ * Reconstructs the absolute path on the host during replay,
13
+ * mapping the original absolute path to a temporary replay directory.
14
+ *
15
+ * @param originalPath The absolute path captured in the artifact
16
+ * @param tempReplayRoot The root of the temporary replay environment
17
+ */
18
+ export declare function mapToReplayEnvironment(originalPath: string, tempReplayRoot: string): string;
19
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAGvD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAoB3F"}
@@ -0,0 +1,43 @@
1
+ import * as path from 'path';
2
+ /**
3
+ * Normalizes a path to consistently use forward slashes (/) across all platforms.
4
+ * This ensures artifact portability between Windows, Linux, and macOS.
5
+ */
6
+ export function normalizeArtifactPath(p) {
7
+ // Use posix-style normalization for the artifact internal representations
8
+ return p.split(path.sep).join(path.posix.sep);
9
+ }
10
+ /**
11
+ * Converts a portable artifact path back to the platform-specific path separator.
12
+ * Useful during replay on a host machine.
13
+ */
14
+ export function toPlatformPath(artifactPath) {
15
+ return artifactPath.split(path.posix.sep).join(path.sep);
16
+ }
17
+ /**
18
+ * Reconstructs the absolute path on the host during replay,
19
+ * mapping the original absolute path to a temporary replay directory.
20
+ *
21
+ * @param originalPath The absolute path captured in the artifact
22
+ * @param tempReplayRoot The root of the temporary replay environment
23
+ */
24
+ export function mapToReplayEnvironment(originalPath, tempReplayRoot) {
25
+ // Strip the leading root from the original path (e.g. C:\ or /)
26
+ // so it can be appended safely to the temp root.
27
+ // Handle Windows absolute paths (e.g., D:\path\to\file or C:/path/to/file)
28
+ // regardless of the current platform, since artifact paths may be cross-platform
29
+ const windowsAbsolutePattern = /^[A-Z]:[/\\]/i;
30
+ if (windowsAbsolutePattern.test(originalPath)) {
31
+ // Strip the drive letter and colon (e.g., "D:\" -> "")
32
+ const pathWithoutRoot = originalPath.slice(2);
33
+ // Normalize to forward slashes for cross-platform consistency
34
+ // Explicitly replace both forward and backward slashes with forward slashes
35
+ const normalized = pathWithoutRoot.replace(/\\/g, '/').replace(/\/+/g, '/');
36
+ return path.posix.join(tempReplayRoot, normalized);
37
+ }
38
+ // Handle Unix absolute paths
39
+ const parsed = path.parse(originalPath);
40
+ const pathWithoutRoot = originalPath.slice(parsed.root.length);
41
+ return path.join(tempReplayRoot, pathWithoutRoot);
42
+ }
43
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,CAAS;IAC7C,0EAA0E;IAC1E,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAChD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,YAAoB;IACjD,OAAO,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,YAAoB,EAAE,cAAsB;IACjF,gEAAgE;IAChE,iDAAiD;IAEjD,2EAA2E;IAC3E,iFAAiF;IACjF,MAAM,sBAAsB,GAAG,eAAe,CAAC;IAC/C,IAAI,sBAAsB,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9C,uDAAuD;QACvD,MAAM,eAAe,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9C,8DAA8D;QAC9D,4EAA4E;QAC5E,MAAM,UAAU,GAAG,eAAe,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC5E,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;IACrD,CAAC;IAED,6BAA6B;IAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxC,MAAM,eAAe,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/D,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,13 @@
1
+ export declare const SECRET_PATTERNS: RegExp[];
2
+ export interface SecretScanResult {
3
+ hasSecrets: boolean;
4
+ detectedKeys: string[];
5
+ }
6
+ export declare function scanEnvironmentForSecrets(env: NodeJS.ProcessEnv): SecretScanResult;
7
+ export declare function buildEnvironmentSchema(env: NodeJS.ProcessEnv, detectedSecrets: string[]): {
8
+ required: string[];
9
+ optional: string[];
10
+ secrets: string[];
11
+ captured_env_keys: string[];
12
+ };
13
+ //# sourceMappingURL=secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/utils/secrets.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,UAU3B,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,gBAAgB,CAwBlF;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,iBAAiB,EAAE,MAAM,EAAE,CAAA;CAAE,CAkBpL"}
@@ -0,0 +1,52 @@
1
+ export const SECRET_PATTERNS = [
2
+ /api_?key/i,
3
+ /secret/i,
4
+ /token/i,
5
+ /password/i,
6
+ /bearer/i,
7
+ /aws_secret_access_key/i,
8
+ /github_token/i,
9
+ /stripe_sk_/i,
10
+ /^[A-Z0-9]{20,128}$/ // Likely tokens (bounded to prevent excessive matching)
11
+ ];
12
+ export function scanEnvironmentForSecrets(env) {
13
+ const detectedKeys = [];
14
+ for (const [key, value] of Object.entries(env)) {
15
+ if (!value)
16
+ continue;
17
+ // Check if key matches known secret patterns
18
+ let isSecret = false;
19
+ for (const pattern of SECRET_PATTERNS) {
20
+ if (pattern.test(key) || (pattern.test(value) && value.length > 15)) {
21
+ isSecret = true;
22
+ break;
23
+ }
24
+ }
25
+ if (isSecret) {
26
+ detectedKeys.push(key);
27
+ }
28
+ }
29
+ return {
30
+ hasSecrets: detectedKeys.length > 0,
31
+ detectedKeys
32
+ };
33
+ }
34
+ export function buildEnvironmentSchema(env, detectedSecrets) {
35
+ // In a real scenario, we'd determine which env vars are actually required by the app.
36
+ // For v0.1, we classify everything non-standard as 'optional' unless explicitly mapped,
37
+ // except secrets which are separated out.
38
+ const standardKeys = ['PATH', 'HOME', 'USER', 'SHELL', 'TEMP', 'TMPDIR', 'USERPROFILE'];
39
+ const optional = [];
40
+ const required = []; // We will let users specify required later, or infer
41
+ const secrets = [...detectedSecrets];
42
+ const captured_env_keys = Object.keys(env);
43
+ for (const key of Object.keys(env)) {
44
+ if (standardKeys.includes(key))
45
+ continue;
46
+ if (secrets.includes(key))
47
+ continue;
48
+ optional.push(key);
49
+ }
50
+ return { required, optional, secrets, captured_env_keys };
51
+ }
52
+ //# sourceMappingURL=secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/utils/secrets.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,WAAW;IACX,SAAS;IACT,QAAQ;IACR,WAAW;IACX,SAAS;IACT,wBAAwB;IACxB,eAAe;IACf,aAAa;IACb,oBAAoB,CAAC,wDAAwD;CAC9E,CAAC;AAOF,MAAM,UAAU,yBAAyB,CAAC,GAAsB;IAC9D,MAAM,YAAY,GAAa,EAAE,CAAC;IAElC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,CAAC,KAAK;YAAE,SAAS;QAErB,6CAA6C;QAC7C,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;YACtC,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC;gBACpE,QAAQ,GAAG,IAAI,CAAC;gBAChB,MAAM;YACR,CAAC;QACH,CAAC;QAED,IAAI,QAAQ,EAAE,CAAC;YACb,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,OAAO;QACL,UAAU,EAAE,YAAY,CAAC,MAAM,GAAG,CAAC;QACnC,YAAY;KACb,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,GAAsB,EAAE,eAAyB;IACtF,sFAAsF;IACtF,wFAAwF;IACxF,0CAA0C;IAC1C,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;IAExF,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAAa,EAAE,CAAC,CAAC,qDAAqD;IACpF,MAAM,OAAO,GAAG,CAAC,GAAG,eAAe,CAAC,CAAC;IACrC,MAAM,iBAAiB,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE3C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,IAAI,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,SAAS;QACzC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,SAAS;QACpC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Security validation utilities for BugProof.
3
+ * Prevents path traversal, command injection, git ref injection,
4
+ * and environment variable hijacking from untrusted artifact data.
5
+ */
6
+ /**
7
+ * Validates that a resolved file path stays within the expected boundary directory.
8
+ * Prevents path traversal attacks via `../` sequences.
9
+ */
10
+ export declare function isPathWithinBoundary(filePath: string, boundaryDir: string): boolean;
11
+ /**
12
+ * Validates a git ref string to prevent flag injection.
13
+ * Git interprets arguments starting with `-` as flags, so we reject those.
14
+ * Accepts: hex commit SHAs, branch names (alphanumeric, dots, slashes, dashes, underscores).
15
+ */
16
+ export declare function isValidGitRef(ref: string): boolean;
17
+ /**
18
+ * Environment variable names that must NEVER be overridden from untrusted artifact data.
19
+ * These can be used to hijack process execution.
20
+ */
21
+ export declare const DANGEROUS_ENV_VARS: Set<string>;
22
+ /**
23
+ * Filters an environment record, removing keys that could hijack execution.
24
+ * Used during replay to prevent artifact environment from overriding critical host vars.
25
+ */
26
+ export declare function sanitizeArtifactEnvironment(artifactEnv: Record<string, string>): Record<string, string>;
27
+ //# sourceMappingURL=security.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/utils/security.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAInF;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOlD;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,aA0B7B,CAAC;AAEH;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAClC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQxB"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Security validation utilities for BugProof.
3
+ * Prevents path traversal, command injection, git ref injection,
4
+ * and environment variable hijacking from untrusted artifact data.
5
+ */
6
+ import * as path from 'path';
7
+ /**
8
+ * Validates that a resolved file path stays within the expected boundary directory.
9
+ * Prevents path traversal attacks via `../` sequences.
10
+ */
11
+ export function isPathWithinBoundary(filePath, boundaryDir) {
12
+ const resolved = path.resolve(filePath);
13
+ const boundary = path.resolve(boundaryDir);
14
+ return resolved.startsWith(boundary + path.sep) || resolved === boundary;
15
+ }
16
+ /**
17
+ * Validates a git ref string to prevent flag injection.
18
+ * Git interprets arguments starting with `-` as flags, so we reject those.
19
+ * Accepts: hex commit SHAs, branch names (alphanumeric, dots, slashes, dashes, underscores).
20
+ */
21
+ export function isValidGitRef(ref) {
22
+ if (!ref || ref.length === 0 || ref.length > 256)
23
+ return false;
24
+ // Must not start with a dash (flag injection)
25
+ if (ref.startsWith('-'))
26
+ return false;
27
+ // Allow hex SHAs or branch-like names
28
+ // Valid chars: a-z, A-Z, 0-9, /, ., _, -
29
+ return /^[a-zA-Z0-9._/-]+$/.test(ref);
30
+ }
31
+ /**
32
+ * Environment variable names that must NEVER be overridden from untrusted artifact data.
33
+ * These can be used to hijack process execution.
34
+ */
35
+ export const DANGEROUS_ENV_VARS = new Set([
36
+ 'PATH',
37
+ 'LD_PRELOAD',
38
+ 'LD_LIBRARY_PATH',
39
+ 'DYLD_INSERT_LIBRARIES',
40
+ 'DYLD_LIBRARY_PATH',
41
+ 'NODE_OPTIONS',
42
+ 'NODE_PATH',
43
+ 'HOME',
44
+ 'USERPROFILE',
45
+ 'SHELL',
46
+ 'COMSPEC',
47
+ 'SYSTEMROOT',
48
+ 'WINDIR',
49
+ 'PYTHONPATH',
50
+ 'RUBYLIB',
51
+ 'PERL5LIB',
52
+ 'TEMP',
53
+ 'TMP',
54
+ 'TMPDIR',
55
+ 'APPDATA',
56
+ 'LOCALAPPDATA',
57
+ 'XDG_RUNTIME_DIR',
58
+ 'NODE_EXTRA_CA_CERTS',
59
+ 'SSL_CERT_FILE',
60
+ 'CURL_CA_BUNDLE',
61
+ ]);
62
+ /**
63
+ * Filters an environment record, removing keys that could hijack execution.
64
+ * Used during replay to prevent artifact environment from overriding critical host vars.
65
+ */
66
+ export function sanitizeArtifactEnvironment(artifactEnv) {
67
+ const safe = {};
68
+ for (const [key, val] of Object.entries(artifactEnv)) {
69
+ if (!DANGEROUS_ENV_VARS.has(key.toUpperCase())) {
70
+ safe[key] = val;
71
+ }
72
+ }
73
+ return safe;
74
+ }
75
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/utils/security.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAgB,EAAE,WAAmB;IACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC3C,OAAO,QAAQ,CAAC,UAAU,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,KAAK,QAAQ,CAAC;AAC3E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG;QAAE,OAAO,KAAK,CAAC;IAC/D,8CAA8C;IAC9C,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACtC,sCAAsC;IACtC,yCAAyC;IACzC,OAAO,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACxC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC;IACxC,MAAM;IACN,YAAY;IACZ,iBAAiB;IACjB,uBAAuB;IACvB,mBAAmB;IACnB,cAAc;IACd,WAAW;IACX,MAAM;IACN,aAAa;IACb,OAAO;IACP,SAAS;IACT,YAAY;IACZ,QAAQ;IACR,YAAY;IACZ,SAAS;IACT,UAAU;IACV,MAAM;IACN,KAAK;IACL,QAAQ;IACR,SAAS;IACT,cAAc;IACd,iBAAiB;IACjB,qBAAqB;IACrB,eAAe;IACf,gBAAgB;CACjB,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CACzC,WAAmC;IAEnC,MAAM,IAAI,GAA2B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QACrD,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YAC/C,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;QAClB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Colored terminal output for BugProof CLI.
3
+ * Uses ANSI codes directly so we avoid ESM-only import issues with chalk v5.
4
+ */
5
+ export declare const c: {
6
+ bold: (t: string) => string;
7
+ dim: (t: string) => string;
8
+ red: (t: string) => string;
9
+ green: (t: string) => string;
10
+ yellow: (t: string) => string;
11
+ blue: (t: string) => string;
12
+ magenta: (t: string) => string;
13
+ cyan: (t: string) => string;
14
+ gray: (t: string) => string;
15
+ };
16
+ export declare const icons: {
17
+ check: string;
18
+ cross: string;
19
+ warning: string;
20
+ arrow: string;
21
+ bug: string;
22
+ box: string;
23
+ dot: string;
24
+ };
25
+ export declare function banner(text: string): void;
26
+ export declare function success(msg: string): void;
27
+ export declare function warn(msg: string): void;
28
+ export declare function error(msg: string): void;
29
+ export declare function info(msg: string): void;
30
+ export declare function kvLine(key: string, value: string): void;
31
+ //# sourceMappingURL=ui.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Colored terminal output for BugProof CLI.
3
+ * Uses ANSI codes directly so we avoid ESM-only import issues with chalk v5.
4
+ */
5
+ const isColorSupported = process.stdout.isTTY && !process.env['NO_COLOR'];
6
+ function wrap(code, resetCode, text) {
7
+ if (!isColorSupported)
8
+ return text;
9
+ return `\x1b[${code}m${text}\x1b[${resetCode}m`;
10
+ }
11
+ export const c = {
12
+ bold: (t) => wrap(1, 22, t),
13
+ dim: (t) => wrap(2, 22, t),
14
+ red: (t) => wrap(31, 39, t),
15
+ green: (t) => wrap(32, 39, t),
16
+ yellow: (t) => wrap(33, 39, t),
17
+ blue: (t) => wrap(34, 39, t),
18
+ magenta: (t) => wrap(35, 39, t),
19
+ cyan: (t) => wrap(36, 39, t),
20
+ gray: (t) => wrap(90, 39, t),
21
+ };
22
+ export const icons = {
23
+ check: isColorSupported ? '\u2714' : '+',
24
+ cross: isColorSupported ? '\u2718' : 'x',
25
+ warning: isColorSupported ? '\u26A0' : '!',
26
+ arrow: isColorSupported ? '\u279C' : '>', // Sleeker arrow
27
+ bug: isColorSupported ? '\uD83E\uDEB2' : '*', // Beetle emoji for modern look
28
+ box: isColorSupported ? '\u25A0' : '#',
29
+ dot: isColorSupported ? '\u2022' : '-',
30
+ };
31
+ export function banner(text) {
32
+ const line = '\u2500'.repeat(Math.max(text.length + 4, 40));
33
+ console.log();
34
+ console.log(c.cyan(`\u256D${line}\u256E`));
35
+ console.log(c.cyan(`\u2502 ${c.bold(text.padEnd(line.length - 2))}\u2502`));
36
+ console.log(c.cyan(`\u2570${line}\u256F`));
37
+ console.log();
38
+ }
39
+ export function success(msg) {
40
+ console.log(` ${c.green(icons.check)} ${msg}`);
41
+ }
42
+ export function warn(msg) {
43
+ console.log(` ${c.yellow(icons.warning)} ${msg}`);
44
+ }
45
+ export function error(msg) {
46
+ console.log(` ${c.red(icons.cross)} ${msg}`);
47
+ }
48
+ export function info(msg) {
49
+ console.log(` ${c.blue(icons.arrow)} ${msg}`);
50
+ }
51
+ export function kvLine(key, value) {
52
+ console.log(` ${c.dim(key.padEnd(16))} ${value}`);
53
+ }
54
+ //# sourceMappingURL=ui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/utils/ui.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "bugproof",
3
+ "version": "0.1.1",
4
+ "description": "Executable bug artifacts — portable, reproducible bug reports",
5
+ "main": "dist/cli.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "bugproof": "dist/cli.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "postinstall": "node scripts/postinstall.cjs",
13
+ "prepublishOnly": "npm run build && npm run test && npm run lint",
14
+ "dev": "tsx watch src/index.ts",
15
+ "test": "jest",
16
+ "test:watch": "jest --watch",
17
+ "test:coverage": "jest --coverage",
18
+ "lint": "eslint src --ext .ts",
19
+ "format": "prettier --write 'src/**/*.ts'",
20
+ "cli": "tsx src/cli.ts",
21
+ "test:e2e": "node scripts/e2e-matrix.js",
22
+ "test:comprehensive": "node scripts/comprehensive-test.js",
23
+ "release": "node scripts/release.cjs"
24
+ },
25
+ "keywords": [
26
+ "bug",
27
+ "reproducible",
28
+ "artifact",
29
+ "cli",
30
+ "debugging",
31
+ "issue-tracking",
32
+ "portable"
33
+ ],
34
+ "author": "BugProof Contributors",
35
+ "license": "MIT",
36
+ "devDependencies": {
37
+ "@types/archiver": "^7.0.0",
38
+ "@types/extract-zip": "^2.0.0",
39
+ "@types/jest": "^29.5.14",
40
+ "@types/node": "^20.0.0",
41
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
42
+ "@typescript-eslint/parser": "^6.0.0",
43
+ "eslint": "^8.0.0",
44
+ "jest": "^29.7.0",
45
+ "node-ssh": "^13.2.1",
46
+ "prettier": "^3.0.0",
47
+ "ts-jest": "^29.4.9",
48
+ "tsx": "^4.0.0",
49
+ "typescript": "^5.0.0"
50
+ },
51
+ "dependencies": {
52
+ "archiver": "^7.0.1",
53
+ "commander": "^11.0.0",
54
+ "extract-zip": "^2.0.1"
55
+ },
56
+ "engines": {
57
+ "node": ">=18.0.0"
58
+ },
59
+ "files": [
60
+ "dist",
61
+ "assets",
62
+ "scripts/bugproof-file-association-*.sh",
63
+ "scripts/bugproof-file-association-*.reg",
64
+ "scripts/postinstall.cjs",
65
+ "README.md",
66
+ "LICENSE",
67
+ "CHANGELOG.md"
68
+ ],
69
+ "directories": {
70
+ "doc": "docs"
71
+ },
72
+ "repository": {
73
+ "type": "git",
74
+ "url": "git+https://github.com/sidinsearch/BugProof.git"
75
+ },
76
+ "bugs": {
77
+ "url": "https://github.com/sidinsearch/BugProof/issues"
78
+ },
79
+ "homepage": "https://github.com/sidinsearch/BugProof#readme"
80
+ }
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env bash
2
+ # BugProof Linux file association setup
3
+ # Registers .bug files and creates MIME type association
4
+
5
+ set -e
6
+
7
+ echo "🐧 Setting up BugProof file associations on Linux..."
8
+
9
+ # Create MIME type file
10
+ MIME_FILE="/usr/share/mime/packages/bugproof-bug.xml"
11
+ if [ -f "$MIME_FILE" ]; then
12
+ echo "✓ MIME type already registered"
13
+ else
14
+ sudo tee "$MIME_FILE" > /dev/null <<'EOF'
15
+ <?xml version="1.0" encoding="UTF-8"?>
16
+ <mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
17
+ <mime-type type="application/x-bugproof">
18
+ <comment>BugProof Bug Artifact</comment>
19
+ <glob pattern="*.bug"/>
20
+ <magic priority="50">
21
+ <match type="string" value="PK\x03\x04" offset="0"/>
22
+ </magic>
23
+ </mime-type>
24
+ </mime-info>
25
+ EOF
26
+ echo "✓ MIME type registered at $MIME_FILE"
27
+ fi
28
+
29
+ # Update MIME database
30
+ if command -v update-mime-database &> /dev/null; then
31
+ sudo update-mime-database /usr/share/mime
32
+ echo "✓ MIME database updated"
33
+ fi
34
+
35
+ # Create .desktop file for replay action
36
+ DESKTOP_REPLAY="/usr/share/applications/bugproof-replay.desktop"
37
+ sudo tee "$DESKTOP_REPLAY" > /dev/null <<'EOF'
38
+ [Desktop Entry]
39
+ Type=Application
40
+ Name=BugProof Replay
41
+ Exec=bugproof replay %F
42
+ MimeType=application/x-bugproof
43
+ Icon=bugproof
44
+ NoDisplay=true
45
+ EOF
46
+ echo "✓ Desktop entry created for replay"
47
+
48
+ # Create .desktop file for inspect action
49
+ DESKTOP_INSPECT="/usr/share/applications/bugproof-inspect.desktop"
50
+ sudo tee "$DESKTOP_INSPECT" > /dev/null <<'EOF'
51
+ [Desktop Entry]
52
+ Type=Application
53
+ Name=BugProof Inspect
54
+ Exec=bugproof inspect %F
55
+ MimeType=application/x-bugproof
56
+ Icon=bugproof
57
+ NoDisplay=true
58
+ EOF
59
+ echo "✓ Desktop entry created for inspect"
60
+
61
+ # Install icon
62
+ ICON_DIR="/usr/share/icons/hicolor/512x512/apps"
63
+ if [ -d "$ICON_DIR" ]; then
64
+ sudo cp assets/icon-512x512.png "$ICON_DIR/bugproof.png" 2>/dev/null || true
65
+ echo "✓ Icon installed to $ICON_DIR"
66
+ fi
67
+
68
+ # Set default handler for .bug files
69
+ if command -v xdg-mime &> /dev/null; then
70
+ xdg-mime default bugproof-replay.desktop application/x-bugproof
71
+ echo "✓ Set default handler to BugProof Replay"
72
+ fi
73
+
74
+ echo ""
75
+ echo "✅ BugProof file association setup complete!"
76
+ echo ""
77
+ echo "🎯 You can now:"
78
+ echo " • Double-click .bug files to replay them"
79
+ echo " • Right-click → Open With → BugProof Replay"
80
+ echo " • Command: bugproof replay artifact.bug"
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env bash
2
+ # BugProof macOS file association setup
3
+ # Registers .bug files for macOS
4
+
5
+ set -e
6
+
7
+ echo "🍎 Setting up BugProof file associations on macOS..."
8
+
9
+ # Create UTType definition
10
+ PLIST_FILE="$HOME/Library/LaunchAgents/com.bugproof.uti.plist"
11
+ mkdir -p "$(dirname "$PLIST_FILE")"
12
+
13
+ cat > "$PLIST_FILE" <<'EOF'
14
+ <?xml version="1.0" encoding="UTF-8"?>
15
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
16
+ <plist version="1.0">
17
+ <dict>
18
+ <key>UTTypeIdentifier</key>
19
+ <string>com.bugproof.artifact</string>
20
+ <key>UTTypeDescription</key>
21
+ <string>BugProof Bug Artifact</string>
22
+ <key>UTTypeConformsTo</key>
23
+ <array>
24
+ <string>public.data</string>
25
+ </array>
26
+ <key>UTTypeTagSpecification</key>
27
+ <dict>
28
+ <key>com.apple.ostype</key>
29
+ <string>BUGF</string>
30
+ <key>public.filename-extension</key>
31
+ <array>
32
+ <string>bug</string>
33
+ </array>
34
+ <key>public.mime-type</key>
35
+ <string>application/x-bugproof</string>
36
+ </dict>
37
+ </dict>
38
+ </plist>
39
+ EOF
40
+
41
+ # Update LaunchServices database
42
+ /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -kill -r -domain local -domain system -domain user
43
+
44
+ echo "✓ macOS UTType registered"
45
+ echo ""
46
+ echo "✅ BugProof file association setup complete on macOS!"
47
+ echo ""
48
+ echo "🎯 You can now double-click .bug files to replay them"
@@ -0,0 +1,44 @@
1
+ Windows Registry Editor Version 5.00
2
+
3
+ ; BugProof .bug file association for Windows
4
+ ; This script associates .bug files with BugProof CLI and assigns an icon
5
+
6
+ [HKEY_CLASSES_ROOT\.bug]
7
+ @="BugProof.Artifact"
8
+
9
+ [HKEY_CLASSES_ROOT\.bug\ShellNew]
10
+ "FileName"=""
11
+
12
+ [HKEY_CLASSES_ROOT\BugProof.Artifact]
13
+ @="BugProof Bug Artifact"
14
+ "AppUserModelID"="BugProof.CLI"
15
+
16
+ [HKEY_CLASSES_ROOT\BugProof.Artifact\DefaultIcon]
17
+ @="C:\\Program Files\\BugProof\\assets\\icon.ico,0"
18
+
19
+ [HKEY_CLASSES_ROOT\BugProof.Artifact\shell]
20
+ @=""
21
+
22
+ [HKEY_CLASSES_ROOT\BugProof.Artifact\shell\open]
23
+ @="Replay"
24
+
25
+ [HKEY_CLASSES_ROOT\BugProof.Artifact\shell\open\command]
26
+ @="cmd.exe /c \"bugproof replay \"%1\"\""
27
+
28
+ [HKEY_CLASSES_ROOT\BugProof.Artifact\shell\inspect]
29
+ @="Inspect"
30
+
31
+ [HKEY_CLASSES_ROOT\BugProof.Artifact\shell\inspect\command]
32
+ @="cmd.exe /c \"bugproof inspect \"%1\" && pause\""
33
+
34
+ ; Add BugProof to PATH via registry (optional, requires admin)
35
+ [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment]
36
+ ; Note: User must manually add BugProof bin to PATH or run: npm link
37
+
38
+ ; Right-click context menu
39
+ [HKEY_CLASSES_ROOT\*\shell\BugProof Capture]
40
+ @="Capture with BugProof"
41
+ "Icon"="C:\\Program Files\\BugProof\\assets\\icon.ico,0"
42
+
43
+ [HKEY_CLASSES_ROOT\*\shell\BugProof Capture\command]
44
+ @="cmd.exe /c \"bugproof capture -- \"%1\"\""