supercov 0.0.2 → 0.0.4

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 (85) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +159 -30
  3. package/bin/supercov.js +10 -0
  4. package/dist/atomic.d.ts +6 -0
  5. package/dist/atomic.d.ts.map +1 -0
  6. package/dist/atomic.js +47 -0
  7. package/dist/atomic.js.map +1 -0
  8. package/dist/buildCache.d.ts +14 -0
  9. package/dist/buildCache.d.ts.map +1 -0
  10. package/dist/buildCache.js +84 -0
  11. package/dist/buildCache.js.map +1 -0
  12. package/dist/cli.js +536 -215
  13. package/dist/cli.js.map +1 -1
  14. package/dist/directInstrumenter.d.ts +8 -0
  15. package/dist/directInstrumenter.d.ts.map +1 -0
  16. package/dist/directInstrumenter.js +70 -0
  17. package/dist/directInstrumenter.js.map +1 -0
  18. package/dist/evidenceArchive.d.ts +35 -0
  19. package/dist/evidenceArchive.d.ts.map +1 -0
  20. package/dist/evidenceArchive.js +101 -0
  21. package/dist/evidenceArchive.js.map +1 -0
  22. package/dist/instrumenter.d.ts.map +1 -1
  23. package/dist/instrumenter.js +251 -41
  24. package/dist/instrumenter.js.map +1 -1
  25. package/dist/integrity.d.ts.map +1 -1
  26. package/dist/integrity.js +27 -0
  27. package/dist/integrity.js.map +1 -1
  28. package/dist/launchSupervisor.d.ts +24 -0
  29. package/dist/launchSupervisor.d.ts.map +1 -0
  30. package/dist/launchSupervisor.js +397 -0
  31. package/dist/launchSupervisor.js.map +1 -0
  32. package/dist/playwright.d.ts +0 -4
  33. package/dist/playwright.d.ts.map +1 -1
  34. package/dist/playwright.js +33 -17
  35. package/dist/playwright.js.map +1 -1
  36. package/dist/playwrightReporter.d.ts.map +1 -1
  37. package/dist/playwrightReporter.js +3 -2
  38. package/dist/playwrightReporter.js.map +1 -1
  39. package/dist/project.d.ts +5 -2
  40. package/dist/project.d.ts.map +1 -1
  41. package/dist/project.js +192 -27
  42. package/dist/project.js.map +1 -1
  43. package/dist/query.d.ts.map +1 -1
  44. package/dist/query.js +29 -21
  45. package/dist/query.js.map +1 -1
  46. package/dist/register.mjs +18 -13
  47. package/dist/register.mjs.map +1 -1
  48. package/dist/reporter.d.ts +6 -10
  49. package/dist/reporter.d.ts.map +1 -1
  50. package/dist/reporter.js +23 -82
  51. package/dist/reporter.js.map +1 -1
  52. package/dist/resolve-loader.d.mts.map +1 -1
  53. package/dist/resolve-loader.mjs +11 -3
  54. package/dist/resolve-loader.mjs.map +1 -1
  55. package/dist/runAnalysis.d.ts +19 -0
  56. package/dist/runAnalysis.d.ts.map +1 -0
  57. package/dist/runAnalysis.js +112 -0
  58. package/dist/runAnalysis.js.map +1 -0
  59. package/dist/runtime.d.ts +2 -2
  60. package/dist/runtime.d.ts.map +1 -1
  61. package/dist/runtime.js +35 -7
  62. package/dist/runtime.js.map +1 -1
  63. package/dist/transport.d.ts +2 -0
  64. package/dist/transport.d.ts.map +1 -1
  65. package/dist/transport.js +13 -5
  66. package/dist/transport.js.map +1 -1
  67. package/dist/types.d.ts +2 -1
  68. package/dist/types.d.ts.map +1 -1
  69. package/dist/vitePlugin.d.ts +1 -0
  70. package/dist/vitePlugin.d.ts.map +1 -1
  71. package/dist/vitePlugin.js +35 -3
  72. package/dist/vitePlugin.js.map +1 -1
  73. package/dist/vitest.js +3 -2
  74. package/dist/vitest.js.map +1 -1
  75. package/dist/vitestReporter.d.ts +17 -2
  76. package/dist/vitestReporter.d.ts.map +1 -1
  77. package/dist/vitestReporter.js +51 -2
  78. package/dist/vitestReporter.js.map +1 -1
  79. package/dist/workspace.d.ts +81 -0
  80. package/dist/workspace.d.ts.map +1 -0
  81. package/dist/workspace.js +501 -0
  82. package/dist/workspace.js.map +1 -0
  83. package/docs/performance.md +107 -0
  84. package/docs/workspace-isolation.md +118 -0
  85. package/package.json +21 -5
@@ -0,0 +1,118 @@
1
+ # Workspace isolation
2
+
3
+ Supercov's primary filesystem guarantee is stronger than “we clean up when the
4
+ command exits”: the user's source and ordinary build artifacts are never
5
+ Supercov's write targets. Cleanup is useful for space, but correctness cannot
6
+ depend on a signal handler running.
7
+
8
+ ## Owned paths
9
+
10
+ For `supercov -- <command>`, every Supercov-created persistent or temporary path
11
+ is below the project's `.supercov/` directory:
12
+
13
+ | Path | Lifetime |
14
+ | --- | --- |
15
+ | `locks/active.json` | Exclusive run or cleanup transaction; removed by its owner, stale owners are recovered. |
16
+ | `work/<run>/state.json` | In-flight lifecycle record; removed after atomic run publication. |
17
+ | `work/<run>/run-publication/` | Incomplete run staging; atomically renamed or removed on recovery. |
18
+ | `evidence/<run>/` | Loose in-flight evidence; packed and removed after publication. |
19
+ | `runs/<run>/` | Immutable `evidence.raw.gz` (manifest plus raw execution evidence) and `run.json`; retained until explicit prune/clean. Derived query views are never cached. |
20
+ | `cache/instrumented-workspace/<project>/` | Stable physical fallback and provider snapshot cache. |
21
+ | `cache/instrumented-workspace/.<project>.staging-*` | Unpublished cache transaction; removed on error or recovery. |
22
+ | `cache/instrumented-workspace/.<project>.previous-*` | Last complete cache generation during publication; restored or removed on recovery. |
23
+ | `cache/instrumented-workspace/<project>/.supercov/server-evidence/<run>/` | Server/background transport shared with local or mounted guest processes; archived and removed after publication, interruption, refresh, or cleanup. |
24
+
25
+ The lower-level runtime retains `/tmp/supercov-server-evidence` only as a
26
+ fallback when it is embedded without the Supercov CLI and no owned transport
27
+ root is configured. Normal CLI runs always inject an owned root, and VM path
28
+ translation maps that same root into the guest mount.
29
+
30
+ ## Current physical fallback
31
+
32
+ Builds and opaque VM/container mounts currently use a stable physical namespace
33
+ at `.supercov/cache/instrumented-workspace/<project>`. Refresh has four states:
34
+
35
+ 1. The last complete source generation remains live while a sibling `staging`
36
+ tree is prepared.
37
+ 2. The live generation is renamed to a uniquely named `previous` tree.
38
+ 3. The complete `staging` tree is renamed to the stable name.
39
+ 4. The obsolete `previous` tree is removed.
40
+
41
+ All publication renames stay on one filesystem and their parent directory is
42
+ fsynced. Recovery treats `staging` as never published. If the stable name is
43
+ missing, recovery restores the newest `previous` generation; if the stable name
44
+ exists, all `previous` generations are obsolete. This covers a normal error,
45
+ SIGKILL, power loss, and host restart at every boundary without trusting a path
46
+ read from a state file.
47
+
48
+ Source files request Node's
49
+ [`COPYFILE_FICLONE`](https://nodejs.org/api/fs.html#fspromisescopyfilesrc-dest-mode)
50
+ mode. On filesystems such as APFS that support reflinks, file contents are
51
+ copy-on-write. Node explicitly falls back to a real copy on unsupported
52
+ filesystems, however, and directory entries must always be recreated. This is
53
+ why the transaction rules remain necessary.
54
+
55
+ An exact fingerprint over application source, dependencies, configuration,
56
+ build mode, instrumenter runtime, build command, Node, OS, and architecture
57
+ allows a complete instrumented output and its manifest to survive a source
58
+ snapshot refresh. Test-only edits do not invalidate it. A missing artifact or
59
+ any key change forces a new build.
60
+
61
+ The stable physical path is not accidental. Some VM/container systems include
62
+ the host mount path in a snapshot identity. A fresh random path per run would
63
+ avoid retention but force a cold machine snapshot every time.
64
+
65
+ ## Why FUSE is not the default
66
+
67
+ A FUSE overlay could present transformed bytes at the original relative paths,
68
+ but it adds a kernel/system extension or privileged mount dependency on common
69
+ developer platforms. Mount teardown also becomes another failure boundary. A
70
+ zero-install `npx supercov` command cannot assume that dependency, so FUSE may
71
+ become an opt-in adapter but is not a safe portable baseline.
72
+
73
+ ## Copy-free target architecture
74
+
75
+ The intended architecture is capability-based rather than one mechanism for
76
+ every runner:
77
+
78
+ - Node [module customization hooks](https://nodejs.org/api/module.html#customization-hooks)
79
+ can return transformed source for ESM and CommonJS without changing files.
80
+ This is appropriate only when the observed loader chain preserves source
81
+ identity and source maps.
82
+ - Vite/Rollup-compatible tools should transform modules in their native plugin
83
+ graph and relocate every Supercov-added cache/output into `.supercov/`.
84
+ - A Node coordinator that later exposes an opaque VM/container mount can lazily
85
+ materialize the transactional physical fallback and replace only that mount.
86
+ - Native/non-Node compilers and remote control planes that never expose reads or
87
+ mounts need explicit adapters or the physical fallback. Supercov must report
88
+ this boundary instead of silently claiming coverage.
89
+
90
+ The command itself may create files that the same test command normally creates.
91
+ Supercov is responsible for ensuring that instrumentation, generated config,
92
+ manifests, evidence, and additional builds do not add writes outside
93
+ `.supercov/`.
94
+
95
+ ## Release blockers for a copy-free mode
96
+
97
+ A copy-free path is not eligible as the default until its regression suite
98
+ proves all of the following:
99
+
100
+ - original and transformed programs remain semantically equivalent;
101
+ - ESM, CommonJS, TypeScript/transpiler, worker, and child-process loader chains
102
+ preserve exact source attribution;
103
+ - test/build configuration and source fingerprints refer to the original tree;
104
+ - output relocation cannot escape `.supercov/`, including plugin-defined
105
+ outputs;
106
+ - an opaque remote mount either receives a complete materialized fallback or is
107
+ rejected clearly;
108
+ - SIGINT, SIGTERM, SIGKILL simulation, concurrent `clean`, ENOSPC, and failed
109
+ rename/copy injection leave no source changes and recover deterministically;
110
+ - retained bytes and startup time are measurably lower than the transactional
111
+ reflink fallback.
112
+
113
+ Until those gates pass, the transactional physical namespace is the conservative
114
+ fallback rather than a temporary-directory mount whose cleanup must succeed.
115
+
116
+ The filesystem gate runs the transaction suite on Linux, macOS, and Windows,
117
+ including reflink/ordinary-copy behavior, internal links or junctions, ENOSPC,
118
+ failed renames, and forced-process-termination recovery.
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "supercov",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Zero-edit, runner-aware coverage completeness for JavaScript test suites",
5
+ "license": "MIT",
5
6
  "repository": {
6
7
  "type": "git",
7
8
  "url": "https://github.com/supercorp-ai/supercov.git"
@@ -14,6 +15,7 @@
14
15
  "files": [
15
16
  "bin",
16
17
  "dist",
18
+ "docs",
17
19
  "README.md"
18
20
  ],
19
21
  "engines": {
@@ -35,10 +37,17 @@
35
37
  "build": "tsc -p tsconfig.build.json",
36
38
  "test": "vitest run tests/unit",
37
39
  "test:types": "tsc --noEmit",
38
- "test:fixture": "npm run build && npm --prefix tests/fixtures/generic-playwright run test:coverage",
40
+ "test:fixture": "npm run build && npm --prefix tests/fixtures/generic-playwright run test:coverage && node scripts/opaque-runner-integration.mjs",
41
+ "test:packed-npx": "node scripts/packed-npx-integration.mjs",
42
+ "test:isolation": "npm run build && node scripts/isolation-integration.mjs",
43
+ "test:filesystem": "npm run build && vitest run tests/unit/atomic.test.ts tests/unit/evidenceArchive.test.ts tests/unit/workspace.test.ts && node scripts/workspace-crash-integration.mjs",
44
+ "test:clang-mcdc": "node scripts/clang-mcdc-oracle.mjs",
45
+ "test:test262": "npm run build && node scripts/test262-equivalence.mjs",
46
+ "benchmark:check": "npm run build && node scripts/benchmark.mjs",
39
47
  "check": "npm run test && npm run test:types",
48
+ "release:check": "npm run check && npm run build && node scripts/isolation-integration.mjs && npm run test:packed-npx && npm run test:clang-mcdc && node scripts/benchmark.mjs",
40
49
  "prepack": "npm run build",
41
- "prepublishOnly": "npm run check"
50
+ "prepublishOnly": "npm run release:check"
42
51
  },
43
52
  "dependencies": {
44
53
  "@babel/generator": "^8.0.0",
@@ -47,7 +56,7 @@
47
56
  "@babel/types": "^8.0.4"
48
57
  },
49
58
  "peerDependencies": {
50
- "@playwright/test": ">=1.50.0",
59
+ "@playwright/test": ">=1.55.0",
51
60
  "vite": ">=5.0.0",
52
61
  "vitest": ">=2.0.0"
53
62
  },
@@ -55,6 +64,9 @@
55
64
  "@playwright/test": {
56
65
  "optional": true
57
66
  },
67
+ "vite": {
68
+ "optional": true
69
+ },
58
70
  "vitest": {
59
71
  "optional": true
60
72
  }
@@ -62,8 +74,12 @@
62
74
  "devDependencies": {
63
75
  "@playwright/test": "1.62.1",
64
76
  "@types/node": "^24.0.0",
77
+ "fast-check": "^4.9.0",
78
+ "test262-harness": "^10.0.0",
65
79
  "typescript": "7.0.2",
66
80
  "vite": "8.2.2",
67
- "vitest": "4.1.11"
81
+ "vitest": "4.1.11",
82
+ "ws": "^8.21.3",
83
+ "yaml": "^2.9.0"
68
84
  }
69
85
  }