doc-detective 4.2.0 → 4.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/package.json +3 -1
- package/scripts/postinstall.js +29 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "doc-detective",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.2",
|
|
4
4
|
"description": "Treat doc content as testable assertions to validate doc accuracy and product UX.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"doc-detective": "bin/doc-detective.js"
|
|
@@ -48,6 +48,8 @@
|
|
|
48
48
|
"dev": "node ./dev",
|
|
49
49
|
"container:build": "node src/container/scripts/build.cjs",
|
|
50
50
|
"container:rebuild": "node src/container/scripts/build.cjs --no-cache",
|
|
51
|
+
"container:build:base": "node src/container/scripts/build.cjs --target=base",
|
|
52
|
+
"container:build:base:push": "node src/container/scripts/build.cjs --target=base --push",
|
|
51
53
|
"container:test": "mocha src/container/test/*.test.cjs --timeout 0"
|
|
52
54
|
},
|
|
53
55
|
"repository": {
|
package/scripts/postinstall.js
CHANGED
|
@@ -63,27 +63,46 @@ async function maybePromptInstallAgents() {
|
|
|
63
63
|
: "PATH";
|
|
64
64
|
const originalPath = process.env[pathKey];
|
|
65
65
|
const pathSep = process.platform === "win32" ? ";" : ":";
|
|
66
|
+
// Windows paths are case-insensitive, so normalize both sides of every
|
|
67
|
+
// comparison to lowercase on win32. Otherwise `C:\Proj\NODE_MODULES\.BIN`
|
|
68
|
+
// would slip past a literal `/node_modules/.bin` check.
|
|
69
|
+
const isWin = process.platform === "win32";
|
|
70
|
+
const caseFold = (s) => (isWin ? s.toLowerCase() : s);
|
|
66
71
|
const initCwdAbs = process.env.INIT_CWD
|
|
67
72
|
? path.resolve(process.env.INIT_CWD)
|
|
68
73
|
: null;
|
|
74
|
+
const initCwdMatch = initCwdAbs ? caseFold(initCwdAbs) : null;
|
|
75
|
+
// Guard against INIT_CWD resolving to a root ("/" on POSIX, "C:\" on
|
|
76
|
+
// Windows): blindly appending path.sep would produce "//" or "C:\\", and
|
|
77
|
+
// `startsWith` would miss every subpath. When the value already ends with
|
|
78
|
+
// a separator (root case), use it as-is; otherwise append.
|
|
79
|
+
const initCwdPrefix =
|
|
80
|
+
initCwdMatch && !initCwdMatch.endsWith(path.sep)
|
|
81
|
+
? initCwdMatch + path.sep
|
|
82
|
+
: initCwdMatch;
|
|
69
83
|
const sanitizedPath = (originalPath || "")
|
|
70
84
|
.split(pathSep)
|
|
71
85
|
.filter((entry) => {
|
|
72
86
|
if (!entry || entry === ".") return false;
|
|
73
|
-
const normalized = entry.split(path.sep).join("/");
|
|
87
|
+
const normalized = caseFold(entry.split(path.sep).join("/"));
|
|
74
88
|
if (normalized.includes("/node_modules/.bin")) return false;
|
|
75
|
-
if (
|
|
76
|
-
const resolved = path.resolve(entry);
|
|
77
|
-
if (
|
|
78
|
-
resolved === initCwdAbs ||
|
|
79
|
-
resolved.startsWith(initCwdAbs + path.sep)
|
|
80
|
-
)
|
|
89
|
+
if (initCwdMatch) {
|
|
90
|
+
const resolved = caseFold(path.resolve(entry));
|
|
91
|
+
if (resolved === initCwdMatch || resolved.startsWith(initCwdPrefix))
|
|
81
92
|
return false;
|
|
82
93
|
}
|
|
83
94
|
return true;
|
|
84
95
|
})
|
|
85
96
|
.join(pathSep);
|
|
86
97
|
process.env[pathKey] = sanitizedPath;
|
|
98
|
+
// Restoring via `process.env[k] = undefined` coerces to the literal string
|
|
99
|
+
// "undefined" (Node stringifies every env value), leaving the process with
|
|
100
|
+
// a broken PATH. Delete the key when the original was absent; only assign
|
|
101
|
+
// when we have a real string.
|
|
102
|
+
const restorePath = () => {
|
|
103
|
+
if (originalPath === undefined) delete process.env[pathKey];
|
|
104
|
+
else process.env[pathKey] = originalPath;
|
|
105
|
+
};
|
|
87
106
|
|
|
88
107
|
// Hard ceiling on the whole detection phase. Some adapters shell out to
|
|
89
108
|
// external CLIs that could hang on auth prompts, proxy stalls, etc. On
|
|
@@ -121,17 +140,17 @@ async function maybePromptInstallAgents() {
|
|
|
121
140
|
);
|
|
122
141
|
const result = await Promise.race([detection, timeout]);
|
|
123
142
|
if (result === "__timeout__") {
|
|
124
|
-
|
|
143
|
+
restorePath();
|
|
125
144
|
// Orphaned adapter children would otherwise keep the event loop alive
|
|
126
145
|
// and freeze `npm install`. See comment above.
|
|
127
146
|
process.exit(0);
|
|
128
147
|
}
|
|
129
148
|
adaptersNeedingInstall = result.filter(Boolean);
|
|
130
149
|
} catch {
|
|
131
|
-
|
|
150
|
+
restorePath();
|
|
132
151
|
return;
|
|
133
152
|
}
|
|
134
|
-
|
|
153
|
+
restorePath();
|
|
135
154
|
|
|
136
155
|
if (adaptersNeedingInstall.length === 0) return;
|
|
137
156
|
|