bugproof 0.1.2 → 0.2.2
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/CHANGELOG.md +61 -5
- package/README.md +175 -4
- package/dist/capture/env-snapshot.d.ts +53 -0
- package/dist/capture/env-snapshot.d.ts.map +1 -0
- package/dist/capture/env-snapshot.js +122 -0
- package/dist/capture/env-snapshot.js.map +1 -0
- package/dist/capture/language-support.d.ts +55 -0
- package/dist/capture/language-support.d.ts.map +1 -0
- package/dist/capture/language-support.js +505 -0
- package/dist/capture/language-support.js.map +1 -0
- package/dist/capture/packager.d.ts +9 -0
- package/dist/capture/packager.d.ts.map +1 -1
- package/dist/capture/packager.js +23 -2
- package/dist/capture/packager.js.map +1 -1
- package/dist/capture/source-strategy.d.ts +52 -0
- package/dist/capture/source-strategy.d.ts.map +1 -0
- package/dist/capture/source-strategy.js +227 -0
- package/dist/capture/source-strategy.js.map +1 -0
- package/dist/cli.js +373 -12
- package/dist/cli.js.map +1 -1
- package/dist/config/loader.d.ts +44 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +87 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/replay/engine.d.ts +9 -0
- package/dist/replay/engine.d.ts.map +1 -1
- package/dist/replay/engine.js +29 -3
- package/dist/replay/engine.js.map +1 -1
- package/dist/replay/hints.d.ts +18 -0
- package/dist/replay/hints.d.ts.map +1 -0
- package/dist/replay/hints.js +138 -0
- package/dist/replay/hints.js.map +1 -0
- package/dist/replay/sandbox.js +41 -14
- package/dist/replay/sandbox.js.map +1 -1
- package/dist/replay/verdict.d.ts.map +1 -1
- package/dist/replay/verdict.js +41 -5
- package/dist/replay/verdict.js.map +1 -1
- package/dist/sandbox/bugbox.d.ts.map +1 -1
- package/dist/sandbox/bugbox.js +40 -6
- package/dist/sandbox/bugbox.js.map +1 -1
- package/dist/sandbox/container.d.ts +81 -0
- package/dist/sandbox/container.d.ts.map +1 -0
- package/dist/sandbox/container.js +343 -0
- package/dist/sandbox/container.js.map +1 -0
- package/dist/sandbox/cross-platform.d.ts +59 -0
- package/dist/sandbox/cross-platform.d.ts.map +1 -0
- package/dist/sandbox/cross-platform.js +330 -0
- package/dist/sandbox/cross-platform.js.map +1 -0
- package/dist/sandbox/network.d.ts.map +1 -1
- package/dist/sandbox/network.js +31 -2
- package/dist/sandbox/network.js.map +1 -1
- package/dist/share/gist.d.ts +21 -0
- package/dist/share/gist.d.ts.map +1 -0
- package/dist/share/gist.js +158 -0
- package/dist/share/gist.js.map +1 -0
- package/dist/utils/archive.d.ts +1 -0
- package/dist/utils/archive.d.ts.map +1 -1
- package/dist/utils/archive.js +42 -1
- package/dist/utils/archive.js.map +1 -1
- package/dist/utils/artifact-validation.d.ts +7 -0
- package/dist/utils/artifact-validation.d.ts.map +1 -0
- package/dist/utils/artifact-validation.js +212 -0
- package/dist/utils/artifact-validation.js.map +1 -0
- package/dist/utils/dependencies.d.ts +18 -0
- package/dist/utils/dependencies.d.ts.map +1 -0
- package/dist/utils/dependencies.js +218 -0
- package/dist/utils/dependencies.js.map +1 -0
- package/package.json +3 -2
- package/scripts/postinstall.cjs +38 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## 0.2.2 - 2026-05-08
|
|
2
|
+
|
|
3
|
+
- Multi-language detection and language-context metadata added (Java, C/C++, Go, Rust, .NET, Ruby).
|
|
4
|
+
- Cross-platform sandbox translation layer: command/path/env mapping to improve Windows↔Linux replays.
|
|
5
|
+
- Improved source strategy and detection for projects without git (stacktrace/minimal modes).
|
|
6
|
+
- Added integration tests and expanded dependency detection across languages.
|
|
7
|
+
- Docs: Developer/engineering overview and cross-platform testing guidance.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
1
11
|
# Changelog
|
|
2
12
|
|
|
3
13
|
All notable changes to BugProof will be documented in this file.
|
|
@@ -46,12 +56,58 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
46
56
|
- File association setup instructions
|
|
47
57
|
- Troubleshooting and FAQ sections
|
|
48
58
|
|
|
49
|
-
## [0.2.0] -
|
|
59
|
+
## [0.2.0] - 2026-05-07
|
|
60
|
+
|
|
61
|
+
### Added
|
|
62
|
+
|
|
63
|
+
- **Watch command** — Run any command with `bugproof watch -- <cmd>` and auto-capture on failure. Transparent pass-through on success. Integrates with `.bugproofrc` config.
|
|
64
|
+
- **Init command** — Generate project-level `.bugproofrc` config with `bugproof init`. Supports exclude patterns, timeout, output directory, name templates.
|
|
65
|
+
- **Share command** — Push artifacts to GitHub Gist with `bugproof share <artifact>`. Creates a formatted README with replay instructions.
|
|
66
|
+
- **Smart Hints** — When replay fails to reproduce, BugProof now suggests actionable fixes (missing packages, env vars, permissions, network issues).
|
|
67
|
+
- **Dependency Detection** — Automatically detects missing dependencies from error output across Node.js, Python, Ruby, Go, Rust, and system libraries. Shows install commands.
|
|
68
|
+
- **Project Config** — `.bugproofrc` file with hierarchical lookup (walks parent directories). Supports exclude, timeout, name templates, and output directory.
|
|
69
|
+
- **Name Templates** — Configurable artifact naming with `{timestamp}`, `{command}`, `{exit_code}` variables.
|
|
70
|
+
|
|
71
|
+
### Fixed
|
|
72
|
+
|
|
73
|
+
- Capture no longer crashes in non-git directories (returns empty file list gracefully)
|
|
74
|
+
- CLI version now reads dynamically from package.json (no more hardcoded mismatch)
|
|
75
|
+
- Flaky test timeout resolved (stderr capture test)
|
|
76
|
+
|
|
77
|
+
### Testing
|
|
78
|
+
|
|
79
|
+
- 24 test suites, 182 passing tests
|
|
80
|
+
- New test coverage: config loader, dependency detection, smart hints, e2e CLI, packager regression
|
|
81
|
+
- End-to-end validation of watch, init, share, and dependency detection workflows
|
|
82
|
+
|
|
83
|
+
## [0.2.1] - 2026-05-07
|
|
84
|
+
|
|
85
|
+
### Added
|
|
86
|
+
|
|
87
|
+
- **Smart Source Strategy** — BugProof now intelligently determines how to include source code:
|
|
88
|
+
- `git-full`: Clean git repo → record commit hash only, zero files shipped (replay uses git checkout)
|
|
89
|
+
- `git-patch`: Dirty git repo → record commit + diff patch (tiny artifact, full reproducibility)
|
|
90
|
+
- `stacktrace`: No git → extract file paths from error stacktrace, ship only those files
|
|
91
|
+
- `minimal`: No git, no stacktrace → command-only artifact
|
|
92
|
+
- **BugBox Container** — Lightweight Docker-like isolation without Docker:
|
|
93
|
+
- Linux: user/PID/mount/network namespaces via `unshare`, fuse-overlayfs, cgroups v2
|
|
94
|
+
- Windows: Job Objects + firewall rules + isolated temp
|
|
95
|
+
- macOS: sandbox-exec profiles with filesystem/network deny rules
|
|
96
|
+
- All platforms: temp directory isolation, env sanitization, auto-cleanup
|
|
97
|
+
- **Environment Snapshot** — Captures runtime versions (Node, Python, Ruby, Go, Rust, Java, npm, pip) at capture time. On replay, warns about mismatches that could affect reproduction.
|
|
98
|
+
- **Replay `--container` flag** — Opt into BugBox container isolation during replay.
|
|
99
|
+
|
|
100
|
+
### Architecture
|
|
101
|
+
|
|
102
|
+
- `src/capture/source-strategy.ts` — Smart source inclusion with tiered git/stacktrace/minimal strategies
|
|
103
|
+
- `src/capture/env-snapshot.ts` — Runtime version probing and cross-snapshot comparison
|
|
104
|
+
- `src/sandbox/container.ts` — Lightweight container with layered isolation (namespace, filesystem, network, resources)
|
|
105
|
+
- Packager now writes `source-strategy.json`, `changes.patch`, and `env-snapshot.json` into artifacts
|
|
106
|
+
|
|
107
|
+
### Testing
|
|
50
108
|
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
- Web UI for artifact inspection
|
|
54
|
-
- Language-specific dependency detection
|
|
109
|
+
- 27 test suites, 204 passing tests
|
|
110
|
+
- New coverage: source strategy (5 tests), env snapshot (5 tests), container (6 tests), stacktrace extraction (5 tests)
|
|
55
111
|
|
|
56
112
|
## [0.3.0] - Planned
|
|
57
113
|
|
package/README.md
CHANGED
|
@@ -180,6 +180,147 @@ bugproof diff --json bug-before.bug bug-after.bug
|
|
|
180
180
|
Options:
|
|
181
181
|
- `--json` Structured JSON output
|
|
182
182
|
|
|
183
|
+
### `bugproof watch [command...]`
|
|
184
|
+
|
|
185
|
+
Run a command transparently — auto-capture a `.bug` artifact only if it fails. This is the everyday command. Replace `npm test` with `bugproof watch -- npm test` in your workflow.
|
|
186
|
+
|
|
187
|
+
Examples:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
bugproof watch -- npm test
|
|
191
|
+
bugproof watch -- python app.py
|
|
192
|
+
bugproof watch -- cargo build
|
|
193
|
+
bugproof watch --always -- node script.js # capture even on success
|
|
194
|
+
bugproof watch -o ./bugs -- go test ./... # output to ./bugs/ directory
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Options:
|
|
198
|
+
- `--timeout <ms>` Command timeout (default: from `.bugproofrc` or 300000)
|
|
199
|
+
- `-n, --name <name>` Artifact name
|
|
200
|
+
- `-d, --description <desc>` Description
|
|
201
|
+
- `-o, --output <dir>` Output directory
|
|
202
|
+
- `--always` Capture even when command succeeds
|
|
203
|
+
- `--json` Structured JSON output
|
|
204
|
+
|
|
205
|
+
### `bugproof init`
|
|
206
|
+
|
|
207
|
+
Create a `.bugproofrc` config file in the current directory.
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
bugproof init
|
|
211
|
+
bugproof init --force # overwrite existing
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Config options (`.bugproofrc`):
|
|
215
|
+
|
|
216
|
+
```json
|
|
217
|
+
{
|
|
218
|
+
"exclude": ["node_modules/**", "dist/**", "*.bug"],
|
|
219
|
+
"outputDir": ".",
|
|
220
|
+
"timeout": 300000,
|
|
221
|
+
"skipSecrets": false,
|
|
222
|
+
"includeUntracked": false,
|
|
223
|
+
"maxArtifactSizeMB": 50,
|
|
224
|
+
"nameTemplate": "bug_{timestamp}"
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Name template variables: `{timestamp}`, `{command}`, `{exit_code}`
|
|
229
|
+
|
|
230
|
+
### `bugproof share <artifact>`
|
|
231
|
+
|
|
232
|
+
Share an artifact via GitHub Gist. Creates a secret gist with manifest, failure info, and a README.
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
bugproof share my-bug.bug
|
|
236
|
+
bugproof share --public my-bug.bug
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Requires `GITHUB_TOKEN` or `BUGPROOF_GITHUB_TOKEN` env var with `gist` scope.
|
|
240
|
+
|
|
241
|
+
Options:
|
|
242
|
+
- `--public` Create a public gist (default: secret/unlisted)
|
|
243
|
+
- `--json` Structured JSON output
|
|
244
|
+
|
|
245
|
+
## Smart Features
|
|
246
|
+
|
|
247
|
+
### Dependency Detection
|
|
248
|
+
|
|
249
|
+
When capturing, BugProof automatically detects missing dependencies from error output:
|
|
250
|
+
|
|
251
|
+
```
|
|
252
|
+
Missing Dependencies Detected
|
|
253
|
+
➜ express (node)
|
|
254
|
+
npm install express
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Supports: Node.js, Python, Ruby, Go, Rust, system libraries.
|
|
258
|
+
|
|
259
|
+
### Smart Hints on Replay
|
|
260
|
+
|
|
261
|
+
When a replay produces a different error than expected, BugProof provides actionable hints:
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
Hints
|
|
265
|
+
➜ Missing Node.js module
|
|
266
|
+
Install the missing package: npm install express
|
|
267
|
+
• Network connectivity issue
|
|
268
|
+
A network connection failed. Check that the required service/host is running.
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Smart Source Strategy
|
|
272
|
+
|
|
273
|
+
BugProof intelligently determines how to include source code, keeping artifacts small even for heavy codebases:
|
|
274
|
+
|
|
275
|
+
| Strategy | Condition | What ships | Artifact size |
|
|
276
|
+
|----------|-----------|------------|---------------|
|
|
277
|
+
| `git-full` | Clean git repo | Commit hash only | ~2 KB |
|
|
278
|
+
| `git-patch` | Dirty git repo | Commit hash + diff patch | ~5 KB |
|
|
279
|
+
| `stacktrace` | No git | Only files from error stacktrace | ~10-50 KB |
|
|
280
|
+
| `minimal` | No git, no stacktrace | Command only | ~1 KB |
|
|
281
|
+
|
|
282
|
+
**Git is strongly encouraged but not required.** Without git, BugProof extracts file paths from your error stacktrace and ships only those files — not your entire codebase.
|
|
283
|
+
|
|
284
|
+
```
|
|
285
|
+
➜ Source: Git repo dirty at 5b7c1131. Shipping commit ref + diff patch (0.2 KB).
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## BugBox Container
|
|
289
|
+
|
|
290
|
+
BugProof includes its own lightweight container sandbox — Docker-like isolation without Docker:
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
bugproof replay --container my-bug.bug # replay with full isolation
|
|
294
|
+
bugproof replay --sandbox full my-bug.bug # alternative: use sandbox layers
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### Isolation layers per platform
|
|
298
|
+
|
|
299
|
+
| Layer | Linux | Windows | macOS |
|
|
300
|
+
|-------|-------|---------|-------|
|
|
301
|
+
| Process isolation | PID namespace (`unshare --pid`) | Job Objects | sandbox-exec |
|
|
302
|
+
| Network isolation | Network namespace (`unshare --net`) | Firewall rules (`netsh`) | sandbox-exec deny |
|
|
303
|
+
| Filesystem | fuse-overlayfs (read-only source + writable overlay) | Isolated temp | Restricted writes |
|
|
304
|
+
| Resource limits | cgroups v2 (memory, CPU, PIDs) | Job Object limits | — |
|
|
305
|
+
| Env sanitization | Strip `LD_PRELOAD`, `NODE_OPTIONS`, etc. | Same | Same |
|
|
306
|
+
| Temp isolation | Private `/tmp` | Private `%TEMP%` | Private `/tmp` |
|
|
307
|
+
|
|
308
|
+
Note for Windows: `isolated` and `full` sandbox modes are best-effort hardening, not VM-grade containment. For untrusted artifacts, replay inside a dedicated VM.
|
|
309
|
+
|
|
310
|
+
No Docker daemon, no images, no 400MB overhead. Just native OS primitives.
|
|
311
|
+
|
|
312
|
+
## Environment Snapshot
|
|
313
|
+
|
|
314
|
+
BugProof captures runtime versions at capture time and warns on replay when versions differ:
|
|
315
|
+
|
|
316
|
+
```
|
|
317
|
+
Environment Mismatches
|
|
318
|
+
• node version mismatch: captured 18.0.0, current 22.1.0
|
|
319
|
+
✘ python 3.11.0 was available at capture but is not installed now.
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Tracked runtimes: Node.js, Python, Ruby, Go, Rust, Java, npm, pip, OS platform, architecture.
|
|
323
|
+
|
|
183
324
|
## File Association and Icon Registration
|
|
184
325
|
|
|
185
326
|
### Windows
|
|
@@ -231,11 +372,18 @@ These project principles remain unchanged:
|
|
|
231
372
|
- [x] v0.1: CLI core (capture/replay/inspect/diff)
|
|
232
373
|
- [x] v0.1: Cross-platform replay support
|
|
233
374
|
- [x] v0.1: Secret redaction and sandbox layers
|
|
234
|
-
- [
|
|
235
|
-
- [
|
|
236
|
-
- [
|
|
237
|
-
- [
|
|
375
|
+
- [x] v0.2: Watch command (auto-capture on failure)
|
|
376
|
+
- [x] v0.2: Project config (`.bugproofrc`)
|
|
377
|
+
- [x] v0.2: Dependency detection (Node/Python/Ruby/Go/Rust)
|
|
378
|
+
- [x] v0.2: Smart hints on replay failure
|
|
379
|
+
- [x] v0.2: Share via GitHub Gist
|
|
380
|
+
- [x] v0.2.1: Smart source strategy (git-full/git-patch/stacktrace/minimal)
|
|
381
|
+
- [x] v0.2.1: BugBox Container (lightweight Docker-like isolation)
|
|
382
|
+
- [x] v0.2.1: Environment snapshot + mismatch warnings
|
|
383
|
+
- [ ] v0.3: Web UI for artifact inspection
|
|
384
|
+
- [ ] v0.3: Artifact signing and verification
|
|
238
385
|
- [ ] v0.4: GitHub issue integration and richer diff visualization
|
|
386
|
+
- [ ] v0.4: CI/CD plugins (GitHub Actions, GitLab CI)
|
|
239
387
|
|
|
240
388
|
## Development
|
|
241
389
|
|
|
@@ -245,6 +393,29 @@ npm run build
|
|
|
245
393
|
npm test
|
|
246
394
|
```
|
|
247
395
|
|
|
396
|
+
## Developer / Engineer Overview
|
|
397
|
+
|
|
398
|
+
This section helps maintainers and integrators understand the architecture, testing, and shipping process for BugProof.
|
|
399
|
+
|
|
400
|
+
- Architecture: modular pipeline (Capture → Packager → Replay → Verdict). Key modules:
|
|
401
|
+
- `src/capture/*` — execution capture and environment snapshot
|
|
402
|
+
- `src/capture/language-support.ts` — multi-language detection and language-context.json generation
|
|
403
|
+
- `src/replay/*` — artifact restore, sandboxing, and verdict generation
|
|
404
|
+
- `src/replay/verdict.ts` — fingerprint and normalized-pattern matching logic
|
|
405
|
+
|
|
406
|
+
- Testing: unit tests (Jest) live under `tests/`; integration tests under `tests/integration/`.
|
|
407
|
+
- Run `npm test` for full suite. Use `npm run test:e2e` for cross-platform orchestrator (requires SSH hosts configured).
|
|
408
|
+
|
|
409
|
+
- Cross-platform QA: use `scripts/e2e-matrix.js` to run Windows↔Linux scenarios. Configure SSH in `scripts/e2e-matrix.js` or provide `E2E_TARGET` env.
|
|
410
|
+
|
|
411
|
+
- Shipping checklist (short):
|
|
412
|
+
1. Ensure `npm run build` passes and `npm test` is green locally on both Windows and Linux runners.
|
|
413
|
+
2. Update `CHANGELOG.md` and bump `package.json` version.
|
|
414
|
+
3. Tag a release `git tag -a vX.Y.Z -m "Release vX.Y.Z"` and push tags.
|
|
415
|
+
4. CI will run `prepublishOnly` and publish on tag events.
|
|
416
|
+
|
|
417
|
+
If you are integrating BugProof into a CI pipeline, prefer running `bugproof inspect` in a hermetic container to validate artifact contents before attempting replay.
|
|
418
|
+
|
|
248
419
|
## CI and Releases
|
|
249
420
|
|
|
250
421
|
- `push` and `pull_request` CI runs only for core paths such as `src/`, `scripts/`, `tests/`, `package.json`, `tsconfig.json`, and `assets/`.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment Snapshot
|
|
3
|
+
*
|
|
4
|
+
* Captures runtime versions (Node.js, Python, Ruby, Go, Rust, Java, etc.)
|
|
5
|
+
* at capture time. On replay, compares against the replayer's environment
|
|
6
|
+
* and warns about mismatches that could affect reproduction.
|
|
7
|
+
*/
|
|
8
|
+
export interface RuntimeVersion {
|
|
9
|
+
name: string;
|
|
10
|
+
version: string;
|
|
11
|
+
path?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface EnvSnapshot {
|
|
14
|
+
/** Node.js runtime */
|
|
15
|
+
node: RuntimeVersion | null;
|
|
16
|
+
/** Python runtime */
|
|
17
|
+
python: RuntimeVersion | null;
|
|
18
|
+
/** Ruby runtime */
|
|
19
|
+
ruby: RuntimeVersion | null;
|
|
20
|
+
/** Go runtime */
|
|
21
|
+
go: RuntimeVersion | null;
|
|
22
|
+
/** Rust/cargo runtime */
|
|
23
|
+
rust: RuntimeVersion | null;
|
|
24
|
+
/** Java runtime */
|
|
25
|
+
java: RuntimeVersion | null;
|
|
26
|
+
/** OS info */
|
|
27
|
+
os: {
|
|
28
|
+
platform: string;
|
|
29
|
+
release: string;
|
|
30
|
+
arch: string;
|
|
31
|
+
};
|
|
32
|
+
/** npm version (if available) */
|
|
33
|
+
npm: RuntimeVersion | null;
|
|
34
|
+
/** pip version (if available) */
|
|
35
|
+
pip: RuntimeVersion | null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Captures the current development environment snapshot.
|
|
39
|
+
* Each probe is fast (<100ms) and never throws.
|
|
40
|
+
*/
|
|
41
|
+
export declare function captureEnvSnapshot(): EnvSnapshot;
|
|
42
|
+
/**
|
|
43
|
+
* Compares two environment snapshots and returns mismatches.
|
|
44
|
+
*/
|
|
45
|
+
export declare function compareEnvSnapshots(captured: EnvSnapshot, current: EnvSnapshot): EnvMismatch[];
|
|
46
|
+
export interface EnvMismatch {
|
|
47
|
+
runtime: string;
|
|
48
|
+
severity: 'error' | 'warning' | 'info';
|
|
49
|
+
message: string;
|
|
50
|
+
capturedVersion: string | null;
|
|
51
|
+
currentVersion: string | null;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=env-snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-snapshot.d.ts","sourceRoot":"","sources":["../../src/capture/env-snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,sBAAsB;IACtB,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;IAC5B,qBAAqB;IACrB,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,mBAAmB;IACnB,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;IAC5B,iBAAiB;IACjB,EAAE,EAAE,cAAc,GAAG,IAAI,CAAC;IAC1B,yBAAyB;IACzB,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;IAC5B,mBAAmB;IACnB,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;IAC5B,cAAc;IACd,EAAE,EAAE;QACF,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,iCAAiC;IACjC,GAAG,EAAE,cAAc,GAAG,IAAI,CAAC;IAC3B,iCAAiC;IACjC,GAAG,EAAE,cAAc,GAAG,IAAI,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,WAAW,CAkBhD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,WAAW,EACrB,OAAO,EAAE,WAAW,GACnB,WAAW,EAAE,CAsDf;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment Snapshot
|
|
3
|
+
*
|
|
4
|
+
* Captures runtime versions (Node.js, Python, Ruby, Go, Rust, Java, etc.)
|
|
5
|
+
* at capture time. On replay, compares against the replayer's environment
|
|
6
|
+
* and warns about mismatches that could affect reproduction.
|
|
7
|
+
*/
|
|
8
|
+
import { spawnSync } from 'child_process';
|
|
9
|
+
import * as os from 'os';
|
|
10
|
+
/**
|
|
11
|
+
* Captures the current development environment snapshot.
|
|
12
|
+
* Each probe is fast (<100ms) and never throws.
|
|
13
|
+
*/
|
|
14
|
+
export function captureEnvSnapshot() {
|
|
15
|
+
return {
|
|
16
|
+
node: probeRuntime('node', ['--version'], /v?([\d.]+)/),
|
|
17
|
+
python: probeRuntime('python', ['--version'], /Python\s+([\d.]+)/)
|
|
18
|
+
?? probeRuntime('python3', ['--version'], /Python\s+([\d.]+)/),
|
|
19
|
+
ruby: probeRuntime('ruby', ['--version'], /ruby\s+([\d.]+)/),
|
|
20
|
+
go: probeRuntime('go', ['version'], /go([\d.]+)/),
|
|
21
|
+
rust: probeRuntime('rustc', ['--version'], /rustc\s+([\d.]+)/),
|
|
22
|
+
java: probeRuntime('java', ['-version'], /version\s+"?([\d.]+)/),
|
|
23
|
+
npm: probeRuntime('npm', ['--version'], /([\d.]+)/),
|
|
24
|
+
pip: probeRuntime('pip', ['--version'], /pip\s+([\d.]+)/)
|
|
25
|
+
?? probeRuntime('pip3', ['--version'], /pip\s+([\d.]+)/),
|
|
26
|
+
os: {
|
|
27
|
+
platform: os.platform(),
|
|
28
|
+
release: os.release(),
|
|
29
|
+
arch: os.arch(),
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Compares two environment snapshots and returns mismatches.
|
|
35
|
+
*/
|
|
36
|
+
export function compareEnvSnapshots(captured, current) {
|
|
37
|
+
const mismatches = [];
|
|
38
|
+
const runtimes = [
|
|
39
|
+
'node', 'python', 'ruby', 'go', 'rust', 'java', 'npm', 'pip',
|
|
40
|
+
];
|
|
41
|
+
for (const key of runtimes) {
|
|
42
|
+
const cap = captured[key];
|
|
43
|
+
const cur = current[key];
|
|
44
|
+
if (cap && !cur) {
|
|
45
|
+
mismatches.push({
|
|
46
|
+
runtime: cap.name,
|
|
47
|
+
severity: 'error',
|
|
48
|
+
message: `${cap.name} ${cap.version} was available at capture but is not installed now.`,
|
|
49
|
+
capturedVersion: cap.version,
|
|
50
|
+
currentVersion: null,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
else if (cap && cur && cap.version !== cur.version) {
|
|
54
|
+
const severity = isMajorMismatch(cap.version, cur.version) ? 'warning' : 'info';
|
|
55
|
+
mismatches.push({
|
|
56
|
+
runtime: cap.name,
|
|
57
|
+
severity,
|
|
58
|
+
message: `${cap.name} version mismatch: captured ${cap.version}, current ${cur.version}`,
|
|
59
|
+
capturedVersion: cap.version,
|
|
60
|
+
currentVersion: cur.version,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// OS platform mismatch
|
|
65
|
+
if (captured.os.platform !== current.os.platform) {
|
|
66
|
+
mismatches.push({
|
|
67
|
+
runtime: 'os',
|
|
68
|
+
severity: 'warning',
|
|
69
|
+
message: `OS mismatch: captured on ${captured.os.platform}, replaying on ${current.os.platform}`,
|
|
70
|
+
capturedVersion: captured.os.platform,
|
|
71
|
+
currentVersion: current.os.platform,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
// Architecture mismatch
|
|
75
|
+
if (captured.os.arch !== current.os.arch) {
|
|
76
|
+
mismatches.push({
|
|
77
|
+
runtime: 'arch',
|
|
78
|
+
severity: 'info',
|
|
79
|
+
message: `Architecture mismatch: captured on ${captured.os.arch}, replaying on ${current.os.arch}`,
|
|
80
|
+
capturedVersion: captured.os.arch,
|
|
81
|
+
currentVersion: current.os.arch,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return mismatches;
|
|
85
|
+
}
|
|
86
|
+
// ── Internal ──
|
|
87
|
+
function probeRuntime(command, args, versionPattern) {
|
|
88
|
+
try {
|
|
89
|
+
const result = spawnSync(command, args, {
|
|
90
|
+
encoding: 'utf-8',
|
|
91
|
+
timeout: 3000,
|
|
92
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
93
|
+
});
|
|
94
|
+
// Java outputs version to stderr
|
|
95
|
+
const output = (result.stdout || '') + (result.stderr || '');
|
|
96
|
+
const match = output.match(versionPattern);
|
|
97
|
+
if (match) {
|
|
98
|
+
// Get the full path
|
|
99
|
+
const whichCmd = os.platform() === 'win32' ? 'where' : 'which';
|
|
100
|
+
const whichResult = spawnSync(whichCmd, [command], {
|
|
101
|
+
encoding: 'utf-8',
|
|
102
|
+
timeout: 2000,
|
|
103
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
104
|
+
});
|
|
105
|
+
return {
|
|
106
|
+
name: command,
|
|
107
|
+
version: match[1],
|
|
108
|
+
path: whichResult.status === 0 ? whichResult.stdout.trim().split('\n')[0] : undefined,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// Not installed or not accessible
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
function isMajorMismatch(v1, v2) {
|
|
118
|
+
const major1 = parseInt(v1.split('.')[0], 10);
|
|
119
|
+
const major2 = parseInt(v2.split('.')[0], 10);
|
|
120
|
+
return !isNaN(major1) && !isNaN(major2) && major1 !== major2;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=env-snapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-snapshot.js","sourceRoot":"","sources":["../../src/capture/env-snapshot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Language Support Module
|
|
3
|
+
*
|
|
4
|
+
* Detects the project's programming language(s) and captures language-specific
|
|
5
|
+
* context needed for cross-platform bug reproduction:
|
|
6
|
+
*
|
|
7
|
+
* - Node.js/TypeScript: package.json, node_modules state, npm/yarn/pnpm lockfiles
|
|
8
|
+
* - Python: requirements.txt, pyproject.toml, virtual env detection
|
|
9
|
+
* - Java/Kotlin: pom.xml, build.gradle, JDK version, classpath
|
|
10
|
+
* - C/C++: Makefile, CMakeLists.txt, compiler version (gcc/clang/msvc)
|
|
11
|
+
* - Go: go.mod, go.sum
|
|
12
|
+
* - Rust: Cargo.toml, Cargo.lock, rustc version
|
|
13
|
+
* - Ruby: Gemfile, Gemfile.lock
|
|
14
|
+
* - .NET/C#: *.csproj, *.sln, dotnet version
|
|
15
|
+
*
|
|
16
|
+
* This information is stored in the artifact so replay can:
|
|
17
|
+
* 1. Warn about missing build tools
|
|
18
|
+
* 2. Suggest dependency installation commands
|
|
19
|
+
* 3. Detect build system differences across platforms
|
|
20
|
+
*/
|
|
21
|
+
export interface LanguageInfo {
|
|
22
|
+
/** Primary language identifier */
|
|
23
|
+
id: string;
|
|
24
|
+
/** Human-readable name */
|
|
25
|
+
name: string;
|
|
26
|
+
/** Detected version of the primary runtime/compiler */
|
|
27
|
+
version: string | null;
|
|
28
|
+
/** Build system used */
|
|
29
|
+
buildSystem: string | null;
|
|
30
|
+
/** Package manager */
|
|
31
|
+
packageManager: string | null;
|
|
32
|
+
/** Lockfile path (relative) if present */
|
|
33
|
+
lockfile: string | null;
|
|
34
|
+
/** Whether a build step is likely needed before running */
|
|
35
|
+
needsBuild: boolean;
|
|
36
|
+
/** Cross-platform compatibility rating */
|
|
37
|
+
crossPlatform: 'native' | 'high' | 'medium' | 'low';
|
|
38
|
+
/** Platform-specific notes */
|
|
39
|
+
notes: string[];
|
|
40
|
+
}
|
|
41
|
+
export interface ProjectLanguageContext {
|
|
42
|
+
/** Detected languages (sorted by confidence) */
|
|
43
|
+
languages: LanguageInfo[];
|
|
44
|
+
/** Primary language (highest confidence) */
|
|
45
|
+
primary: LanguageInfo | null;
|
|
46
|
+
/** Build commands needed for reproduction */
|
|
47
|
+
buildCommands: string[];
|
|
48
|
+
/** Files critical for reproduction (lockfiles, configs) */
|
|
49
|
+
criticalFiles: string[];
|
|
50
|
+
/** Cross-platform warnings specific to this project */
|
|
51
|
+
warnings: string[];
|
|
52
|
+
}
|
|
53
|
+
/** Detect project languages and capture context */
|
|
54
|
+
export declare function detectProjectLanguages(workingDir: string): ProjectLanguageContext;
|
|
55
|
+
//# sourceMappingURL=language-support.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"language-support.d.ts","sourceRoot":"","sources":["../../src/capture/language-support.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAOH,MAAM,WAAW,YAAY;IAC3B,kCAAkC;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,wBAAwB;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,sBAAsB;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,2DAA2D;IAC3D,UAAU,EAAE,OAAO,CAAC;IACpB,0CAA0C;IAC1C,aAAa,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACpD,8BAA8B;IAC9B,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,gDAAgD;IAChD,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,4CAA4C;IAC5C,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IAC7B,6CAA6C;IAC7C,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,2DAA2D;IAC3D,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,uDAAuD;IACvD,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,mDAAmD;AACnD,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,sBAAsB,CAmCjF"}
|