doc-detective 4.1.1 → 4.2.0
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/dist/agents/runner.d.ts.map +1 -1
- package/dist/agents/runner.js +36 -18
- package/dist/agents/runner.js.map +1 -1
- package/package.json +1 -1
- package/scripts/postinstall.js +184 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/agents/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAE/E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEtD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE;QACR,UAAU,EAAE,CAAC,SAAS,EAAE,YAAY,EAAE,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7D,SAAS,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;KACnD,CAAC;IACF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,QAAQ,KAAK,IAAI,CAAC;IACrD,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC;CACvB;AAOD,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,iBAAiB,EACvB,IAAI,GAAE,UAAe,GACpB,OAAO,CAAC,aAAa,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/agents/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAE/E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEtD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE;QACR,UAAU,EAAE,CAAC,SAAS,EAAE,YAAY,EAAE,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7D,SAAS,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;KACnD,CAAC;IACF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,QAAQ,KAAK,IAAI,CAAC;IACrD,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC;CACvB;AAOD,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,iBAAiB,EACvB,IAAI,GAAE,UAAe,GACpB,OAAO,CAAC,aAAa,EAAE,CAAC,CAoF1B"}
|
package/dist/agents/runner.js
CHANGED
|
@@ -35,31 +35,49 @@ export async function runInstallAgents(argv, deps = {}) {
|
|
|
35
35
|
});
|
|
36
36
|
// Install each in order; collect reports. When an adapter doesn't support
|
|
37
37
|
// the requested scope, degrade to its nearest supported scope and attach a
|
|
38
|
-
// note to the report so callers see the divergence.
|
|
38
|
+
// note to the report so callers see the divergence. Each install() is
|
|
39
|
+
// isolated so one adapter's failure doesn't prevent the remaining adapters
|
|
40
|
+
// from getting a chance — otherwise the user who said "install into these
|
|
41
|
+
// three" would lose the last two when the first one errors.
|
|
39
42
|
const reports = [];
|
|
43
|
+
const failures = [];
|
|
40
44
|
for (const adapter of targeted) {
|
|
41
45
|
const effective = effectiveScopeFor(adapter, scope);
|
|
42
46
|
if (effective.degraded) {
|
|
43
47
|
logger(`⚠ ${adapter.displayName} does not support ${scope} scope — installing as ${effective.scope}.`, "warn");
|
|
44
48
|
}
|
|
45
49
|
logger(`\n→ ${adapter.displayName} (${adapter.id}) — scope: ${effective.scope}`, "info");
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
50
|
+
try {
|
|
51
|
+
const report = await adapter.install({
|
|
52
|
+
scope: effective.scope,
|
|
53
|
+
force: Boolean(argv.force),
|
|
54
|
+
dryRun,
|
|
55
|
+
logger,
|
|
56
|
+
});
|
|
57
|
+
const finalReport = effective.degraded
|
|
58
|
+
? {
|
|
59
|
+
...report,
|
|
60
|
+
notes: [
|
|
61
|
+
...(report.notes ?? []),
|
|
62
|
+
`Requested scope '${scope}' is not supported by ${adapter.displayName}; installed as '${effective.scope}' instead.`,
|
|
63
|
+
],
|
|
64
|
+
}
|
|
65
|
+
: report;
|
|
66
|
+
reports.push(finalReport);
|
|
67
|
+
logger(summarizeReport(finalReport), "info");
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
failures.push({ adapter, error: err });
|
|
71
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
72
|
+
logger(` failed: ${message}`, "error");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (failures.length > 0) {
|
|
76
|
+
const names = failures.map((f) => f.adapter.displayName).join(", ");
|
|
77
|
+
// Throw so the CLI exits nonzero and the postinstall prompt's retry hint
|
|
78
|
+
// fires; earlier adapters that succeeded still completed their side
|
|
79
|
+
// effects, they just don't show up in the thrown error's message.
|
|
80
|
+
throw new Error(`Agent install failed for: ${names}.`);
|
|
63
81
|
}
|
|
64
82
|
return reports;
|
|
65
83
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/agents/runner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAa7C,MAAM,aAAa,GAAG,CAAC,GAAW,EAAE,QAAkB,MAAM,EAAE,EAAE;IAC9D,IAAI,KAAK,KAAK,OAAO;QAAE,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;;QACrC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACxB,CAAC,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAuB,EACvB,OAAmB,EAAE;IAErB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,YAAY,EAAE,CAAC;IACjD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,aAAa,CAAC;IAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAEjE,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,CAAC;IAExC,2DAA2D;IAC3D,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CACb,oEAAoE,CACrE,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,kCAAkC;IAClC,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE;QACzD,KAAK,EAAE,KAAK,EAAE;QACd,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,MAAM;KACP,CAAC,CAAC;IACH,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,iBAAiB;IACjB,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE;QAC/C,KAAK,EAAE,KAAK,EAAE;QACd,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC,CAAC;IAEH,0EAA0E;IAC1E,2EAA2E;IAC3E,
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/agents/runner.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/scripts/postinstall.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import {
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
3
4
|
import * as browsers from "@puppeteer/browsers";
|
|
4
5
|
import * as geckodriver from "geckodriver";
|
|
5
6
|
|
|
@@ -8,10 +9,192 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
8
9
|
async function main() {
|
|
9
10
|
await installBrowsers();
|
|
10
11
|
// await installAppiumDepencencies();
|
|
12
|
+
await maybePromptInstallAgents();
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
main();
|
|
14
16
|
|
|
17
|
+
async function maybePromptInstallAgents() {
|
|
18
|
+
// Don't prompt in non-interactive contexts. npm sets many of these during
|
|
19
|
+
// automated installs (CI, Docker builds, `npm install --silent`, etc.), and a
|
|
20
|
+
// blocking prompt there would hang the parent install.
|
|
21
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) return;
|
|
22
|
+
if (process.env.CI) return;
|
|
23
|
+
if (process.env.DOC_DETECTIVE_SKIP_AGENT_PROMPT) return;
|
|
24
|
+
|
|
25
|
+
let listAdapters;
|
|
26
|
+
try {
|
|
27
|
+
const registryPath = path.join(__dirname, "..", "dist", "agents", "registry.js");
|
|
28
|
+
({ listAdapters } = await import(pathToFileURL(registryPath).href));
|
|
29
|
+
} catch {
|
|
30
|
+
// Compiled agents module isn't present (e.g., dev checkout without a build,
|
|
31
|
+
// or a partial install). Skip silently — postinstall must never fail.
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// NOTE: do NOT chdir() to INIT_CWD here. Adapter detect()/getInstallState()
|
|
36
|
+
// implementations spawn bare commands (e.g., `claude --version`), and on
|
|
37
|
+
// Windows CreateProcess searches the cwd before PATH. Running with cwd set
|
|
38
|
+
// to a (potentially untrusted) user repo would let a hostile `claude.cmd`
|
|
39
|
+
// or `claude.exe` in that repo execute during `npm install`. The tradeoff
|
|
40
|
+
// is that project-scope `.claude/`-style files in the consuming repo won't
|
|
41
|
+
// be seen here — we accept occasional over-prompting in that case. The
|
|
42
|
+
// child CLI spawn below gets INIT_CWD explicitly since the user has
|
|
43
|
+
// consented by then and we invoke node with an absolute path.
|
|
44
|
+
const targetCwd = process.env.INIT_CWD || process.cwd();
|
|
45
|
+
|
|
46
|
+
// npm prepends `node_modules/.bin` (and every ancestor's .bin) onto PATH for
|
|
47
|
+
// lifecycle scripts, so a malicious transitive dep declaring `bin: { claude }`
|
|
48
|
+
// could ship a fake `claude` binary that an adapter's bare-command spawn
|
|
49
|
+
// would pick up. Sanitize PATH for detection AND pass the sanitized PATH
|
|
50
|
+
// through to the child CLI spawn — legitimate `claude`/`gh`/etc binaries
|
|
51
|
+
// always come from system or user-global bin dirs, never from a project's
|
|
52
|
+
// `node_modules/.bin`, so stripping those entries is safe throughout.
|
|
53
|
+
//
|
|
54
|
+
// On Windows the PATH env var can be spelled `Path` or `PATH` depending on
|
|
55
|
+
// how the parent process populated its environment. Node's process.env is
|
|
56
|
+
// case-insensitive for reads on Windows, but assigning `process.env.PATH`
|
|
57
|
+
// when the underlying entry is `Path` creates a second entry — so resolve
|
|
58
|
+
// the actual key once and use it consistently.
|
|
59
|
+
const pathKey =
|
|
60
|
+
process.platform === "win32"
|
|
61
|
+
? Object.keys(process.env).find((k) => k.toUpperCase() === "PATH") ||
|
|
62
|
+
"Path"
|
|
63
|
+
: "PATH";
|
|
64
|
+
const originalPath = process.env[pathKey];
|
|
65
|
+
const pathSep = process.platform === "win32" ? ";" : ":";
|
|
66
|
+
const initCwdAbs = process.env.INIT_CWD
|
|
67
|
+
? path.resolve(process.env.INIT_CWD)
|
|
68
|
+
: null;
|
|
69
|
+
const sanitizedPath = (originalPath || "")
|
|
70
|
+
.split(pathSep)
|
|
71
|
+
.filter((entry) => {
|
|
72
|
+
if (!entry || entry === ".") return false;
|
|
73
|
+
const normalized = entry.split(path.sep).join("/");
|
|
74
|
+
if (normalized.includes("/node_modules/.bin")) return false;
|
|
75
|
+
if (initCwdAbs) {
|
|
76
|
+
const resolved = path.resolve(entry);
|
|
77
|
+
if (
|
|
78
|
+
resolved === initCwdAbs ||
|
|
79
|
+
resolved.startsWith(initCwdAbs + path.sep)
|
|
80
|
+
)
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
return true;
|
|
84
|
+
})
|
|
85
|
+
.join(pathSep);
|
|
86
|
+
process.env[pathKey] = sanitizedPath;
|
|
87
|
+
|
|
88
|
+
// Hard ceiling on the whole detection phase. Some adapters shell out to
|
|
89
|
+
// external CLIs that could hang on auth prompts, proxy stalls, etc. On
|
|
90
|
+
// timeout we return — but because Promise.race doesn't cancel the detection
|
|
91
|
+
// promise, any spawned adapter child processes keep the event loop alive
|
|
92
|
+
// and `npm install` would still hang. Force-exit on timeout to tear them
|
|
93
|
+
// down. This is safe here: maybePromptInstallAgents is the last step in
|
|
94
|
+
// main(), the browser installs have already completed, and we're exiting
|
|
95
|
+
// cleanly with code 0.
|
|
96
|
+
const DETECTION_TIMEOUT_MS = 10_000;
|
|
97
|
+
|
|
98
|
+
let adaptersNeedingInstall;
|
|
99
|
+
try {
|
|
100
|
+
const adapters = listAdapters();
|
|
101
|
+
const detection = Promise.all(
|
|
102
|
+
adapters.map(async (adapter) => {
|
|
103
|
+
try {
|
|
104
|
+
const detect = await adapter.detect();
|
|
105
|
+
if (!detect.present) return null;
|
|
106
|
+
const scopes = adapter.supportsScopes();
|
|
107
|
+
const states = await Promise.all(
|
|
108
|
+
scopes.map((s) =>
|
|
109
|
+
adapter.getInstallState(s).catch(() => ({ installed: false }))
|
|
110
|
+
)
|
|
111
|
+
);
|
|
112
|
+
if (states.some((s) => s.installed)) return null;
|
|
113
|
+
return adapter;
|
|
114
|
+
} catch {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
);
|
|
119
|
+
const timeout = new Promise((resolve) =>
|
|
120
|
+
setTimeout(() => resolve("__timeout__"), DETECTION_TIMEOUT_MS).unref()
|
|
121
|
+
);
|
|
122
|
+
const result = await Promise.race([detection, timeout]);
|
|
123
|
+
if (result === "__timeout__") {
|
|
124
|
+
process.env[pathKey] = originalPath;
|
|
125
|
+
// Orphaned adapter children would otherwise keep the event loop alive
|
|
126
|
+
// and freeze `npm install`. See comment above.
|
|
127
|
+
process.exit(0);
|
|
128
|
+
}
|
|
129
|
+
adaptersNeedingInstall = result.filter(Boolean);
|
|
130
|
+
} catch {
|
|
131
|
+
process.env[pathKey] = originalPath;
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
process.env[pathKey] = originalPath;
|
|
135
|
+
|
|
136
|
+
if (adaptersNeedingInstall.length === 0) return;
|
|
137
|
+
|
|
138
|
+
let confirm;
|
|
139
|
+
try {
|
|
140
|
+
({ confirm } = await import("@inquirer/prompts"));
|
|
141
|
+
} catch {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const names = adaptersNeedingInstall.map((a) => a.displayName).join(", ");
|
|
146
|
+
console.log(
|
|
147
|
+
`\nDetected coding agents that may be missing doc-detective tools: ${names}.`
|
|
148
|
+
);
|
|
149
|
+
let proceed = false;
|
|
150
|
+
try {
|
|
151
|
+
proceed = await confirm({
|
|
152
|
+
message: "Install doc-detective agent tools now?",
|
|
153
|
+
default: false,
|
|
154
|
+
});
|
|
155
|
+
} catch {
|
|
156
|
+
// User cancelled (Ctrl+C) or prompt failed — treat as decline.
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (!proceed) {
|
|
160
|
+
console.log(
|
|
161
|
+
"Skipped. Run `npx doc-detective install-agents` later to install."
|
|
162
|
+
);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Pre-fill --agent so the CLI doesn't re-prompt for the picker. Scope stays
|
|
167
|
+
// interactive on purpose — project vs global is a per-user decision.
|
|
168
|
+
const cliPath = path.join(__dirname, "..", "bin", "doc-detective.js");
|
|
169
|
+
const cliArgs = ["install-agents"];
|
|
170
|
+
for (const a of adaptersNeedingInstall) {
|
|
171
|
+
cliArgs.push("--agent", a.id);
|
|
172
|
+
}
|
|
173
|
+
// Hand the child the sanitized PATH under the actual key (PATH or Path) so
|
|
174
|
+
// its adapter spawns can't resolve a fake `claude`/`gh`/etc from
|
|
175
|
+
// `node_modules/.bin` during the install step either.
|
|
176
|
+
const childEnv = { ...process.env, [pathKey]: sanitizedPath };
|
|
177
|
+
const { code, signal } = await new Promise((resolve) => {
|
|
178
|
+
const child = spawn(process.execPath, [cliPath, ...cliArgs], {
|
|
179
|
+
stdio: "inherit",
|
|
180
|
+
cwd: targetCwd,
|
|
181
|
+
env: childEnv,
|
|
182
|
+
});
|
|
183
|
+
// Use `close` (fires after all stdio is flushed) and capture signal so a
|
|
184
|
+
// signal-terminated child (code === null) is treated as failure rather
|
|
185
|
+
// than silently succeeding.
|
|
186
|
+
child.on("close", (c, s) => resolve({ code: c, signal: s }));
|
|
187
|
+
child.on("error", () => resolve({ code: 1, signal: null }));
|
|
188
|
+
});
|
|
189
|
+
if (signal || (code !== null && code !== 0)) {
|
|
190
|
+
const reason = signal ? `due to signal ${signal}` : `with code ${code}`;
|
|
191
|
+
console.log(
|
|
192
|
+
`\ndoc-detective install-agents exited ${reason}. ` +
|
|
193
|
+
"You can retry with `npx doc-detective install-agents`."
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
15
198
|
async function installBrowsers() {
|
|
16
199
|
// Move to package root directory to correctly set browser snapshot directory
|
|
17
200
|
let cwd = process.cwd();
|