@opencodehub/cli 0.1.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/LICENSE +202 -0
- package/README.md +85 -0
- package/dist/agent-context.d.ts +54 -0
- package/dist/agent-context.d.ts.map +1 -0
- package/dist/agent-context.js +122 -0
- package/dist/agent-context.js.map +1 -0
- package/dist/cobol-proleap-setup.d.ts +77 -0
- package/dist/cobol-proleap-setup.d.ts.map +1 -0
- package/dist/cobol-proleap-setup.js +289 -0
- package/dist/cobol-proleap-setup.js.map +1 -0
- package/dist/commands/analyze.d.ts +234 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +1096 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/augment.d.ts +48 -0
- package/dist/commands/augment.d.ts.map +1 -0
- package/dist/commands/augment.js +249 -0
- package/dist/commands/augment.js.map +1 -0
- package/dist/commands/baseline.d.ts +68 -0
- package/dist/commands/baseline.d.ts.map +1 -0
- package/dist/commands/baseline.js +110 -0
- package/dist/commands/baseline.js.map +1 -0
- package/dist/commands/bench.d.ts +54 -0
- package/dist/commands/bench.d.ts.map +1 -0
- package/dist/commands/bench.js +283 -0
- package/dist/commands/bench.js.map +1 -0
- package/dist/commands/ci-init.d.ts +37 -0
- package/dist/commands/ci-init.d.ts.map +1 -0
- package/dist/commands/ci-init.js +115 -0
- package/dist/commands/ci-init.js.map +1 -0
- package/dist/commands/clean.d.ts +13 -0
- package/dist/commands/clean.d.ts.map +1 -0
- package/dist/commands/clean.js +38 -0
- package/dist/commands/clean.js.map +1 -0
- package/dist/commands/code-pack.d.ts +105 -0
- package/dist/commands/code-pack.d.ts.map +1 -0
- package/dist/commands/code-pack.js +187 -0
- package/dist/commands/code-pack.js.map +1 -0
- package/dist/commands/context.d.ts +30 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +237 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/detect-changes.d.ts +26 -0
- package/dist/commands/detect-changes.d.ts.map +1 -0
- package/dist/commands/detect-changes.js +73 -0
- package/dist/commands/detect-changes.js.map +1 -0
- package/dist/commands/doctor.d.ts +52 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +472 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/find-enclosing-symbol.d.ts +67 -0
- package/dist/commands/find-enclosing-symbol.d.ts.map +1 -0
- package/dist/commands/find-enclosing-symbol.js +106 -0
- package/dist/commands/find-enclosing-symbol.js.map +1 -0
- package/dist/commands/group.d.ts +123 -0
- package/dist/commands/group.d.ts.map +1 -0
- package/dist/commands/group.js +448 -0
- package/dist/commands/group.js.map +1 -0
- package/dist/commands/impact.d.ts +23 -0
- package/dist/commands/impact.d.ts.map +1 -0
- package/dist/commands/impact.js +91 -0
- package/dist/commands/impact.js.map +1 -0
- package/dist/commands/index-repo.d.ts +39 -0
- package/dist/commands/index-repo.d.ts.map +1 -0
- package/dist/commands/index-repo.js +148 -0
- package/dist/commands/index-repo.js.map +1 -0
- package/dist/commands/ingest-sarif.d.ts +64 -0
- package/dist/commands/ingest-sarif.d.ts.map +1 -0
- package/dist/commands/ingest-sarif.js +381 -0
- package/dist/commands/ingest-sarif.js.map +1 -0
- package/dist/commands/init.d.ts +75 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +315 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +17 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +79 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/mcp.d.ts +8 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +28 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/open-store.d.ts +25 -0
- package/dist/commands/open-store.d.ts.map +1 -0
- package/dist/commands/open-store.js +47 -0
- package/dist/commands/open-store.js.map +1 -0
- package/dist/commands/pack.d.ts +35 -0
- package/dist/commands/pack.d.ts.map +1 -0
- package/dist/commands/pack.js +83 -0
- package/dist/commands/pack.js.map +1 -0
- package/dist/commands/query.d.ts +85 -0
- package/dist/commands/query.d.ts.map +1 -0
- package/dist/commands/query.js +309 -0
- package/dist/commands/query.js.map +1 -0
- package/dist/commands/scan.d.ts +81 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +407 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/setup.d.ts +178 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +370 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/sql.d.ts +19 -0
- package/dist/commands/sql.d.ts.map +1 -0
- package/dist/commands/sql.js +51 -0
- package/dist/commands/sql.js.map +1 -0
- package/dist/commands/status.d.ts +13 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +66 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/verdict-render.d.ts +33 -0
- package/dist/commands/verdict-render.d.ts.map +1 -0
- package/dist/commands/verdict-render.js +123 -0
- package/dist/commands/verdict-render.js.map +1 -0
- package/dist/commands/verdict.d.ts +61 -0
- package/dist/commands/verdict.d.ts.map +1 -0
- package/dist/commands/verdict.js +146 -0
- package/dist/commands/verdict.js.map +1 -0
- package/dist/commands/wiki.d.ts +26 -0
- package/dist/commands/wiki.d.ts.map +1 -0
- package/dist/commands/wiki.js +74 -0
- package/dist/commands/wiki.js.map +1 -0
- package/dist/editors/claude-code.d.ts +23 -0
- package/dist/editors/claude-code.d.ts.map +1 -0
- package/dist/editors/claude-code.js +58 -0
- package/dist/editors/claude-code.js.map +1 -0
- package/dist/editors/codex.d.ts +22 -0
- package/dist/editors/codex.d.ts.map +1 -0
- package/dist/editors/codex.js +59 -0
- package/dist/editors/codex.js.map +1 -0
- package/dist/editors/cursor.d.ts +13 -0
- package/dist/editors/cursor.d.ts.map +1 -0
- package/dist/editors/cursor.js +21 -0
- package/dist/editors/cursor.js.map +1 -0
- package/dist/editors/index.d.ts +12 -0
- package/dist/editors/index.d.ts.map +1 -0
- package/dist/editors/index.js +11 -0
- package/dist/editors/index.js.map +1 -0
- package/dist/editors/opencode.d.ts +23 -0
- package/dist/editors/opencode.d.ts.map +1 -0
- package/dist/editors/opencode.js +61 -0
- package/dist/editors/opencode.js.map +1 -0
- package/dist/editors/types.d.ts +33 -0
- package/dist/editors/types.d.ts.map +1 -0
- package/dist/editors/types.js +19 -0
- package/dist/editors/types.js.map +1 -0
- package/dist/editors/windows-wrap.d.ts +19 -0
- package/dist/editors/windows-wrap.d.ts.map +1 -0
- package/dist/editors/windows-wrap.js +28 -0
- package/dist/editors/windows-wrap.js.map +1 -0
- package/dist/editors/windsurf.d.ts +12 -0
- package/dist/editors/windsurf.d.ts.map +1 -0
- package/dist/editors/windsurf.js +21 -0
- package/dist/editors/windsurf.js.map +1 -0
- package/dist/embedder-downloader.d.ts +87 -0
- package/dist/embedder-downloader.d.ts.map +1 -0
- package/dist/embedder-downloader.js +261 -0
- package/dist/embedder-downloader.js.map +1 -0
- package/dist/fs-atomic.d.ts +22 -0
- package/dist/fs-atomic.d.ts.map +1 -0
- package/dist/fs-atomic.js +28 -0
- package/dist/fs-atomic.js.map +1 -0
- package/dist/groups.d.ts +64 -0
- package/dist/groups.d.ts.map +1 -0
- package/dist/groups.js +172 -0
- package/dist/groups.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +703 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/is-indexed.d.ts +20 -0
- package/dist/lib/is-indexed.d.ts.map +1 -0
- package/dist/lib/is-indexed.js +35 -0
- package/dist/lib/is-indexed.js.map +1 -0
- package/dist/registry.d.ts +64 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +145 -0
- package/dist/registry.js.map +1 -0
- package/dist/scip-downloader.d.ts +138 -0
- package/dist/scip-downloader.d.ts.map +1 -0
- package/dist/scip-downloader.js +372 -0
- package/dist/scip-downloader.js.map +1 -0
- package/dist/scip-pins.d.ts +99 -0
- package/dist/scip-pins.d.ts.map +1 -0
- package/dist/scip-pins.js +195 -0
- package/dist/scip-pins.js.map +1 -0
- package/dist/skills-gen.d.ts +47 -0
- package/dist/skills-gen.d.ts.map +1 -0
- package/dist/skills-gen.js +292 -0
- package/dist/skills-gen.js.map +1 -0
- package/package.json +81 -0
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codehub scan [path]` — run P1 + profile-gated P2 scanners, emit merged
|
|
3
|
+
* SARIF, ingest findings into the graph.
|
|
4
|
+
*
|
|
5
|
+
* Flow:
|
|
6
|
+
* 1. Resolve the target repo (optionally from the registry).
|
|
7
|
+
* 2. Read the ProjectProfile row (if any) so we can gate scanners by
|
|
8
|
+
* detected languages / iacTypes / apiContracts.
|
|
9
|
+
* 3. Filter the catalog by --scanners, --with, and the profile:
|
|
10
|
+
* - P1 scanners are gated by language overlap (polyglot always in).
|
|
11
|
+
* - P2 scanners (trivy, checkov, hadolint, tflint, spectral) are
|
|
12
|
+
* opt-in via ProjectProfile fields. `--with trivy,checkov`
|
|
13
|
+
* force-adds them regardless of profile.
|
|
14
|
+
* 4. Build per-scanner context (checkov frameworks, hadolint Dockerfile
|
|
15
|
+
* list, spectral contract files, pip-audit requirements path) from
|
|
16
|
+
* the profile + filesystem probe.
|
|
17
|
+
* 5. Run the selected scanners in parallel via `runScanners`.
|
|
18
|
+
* 6. Merge SARIF and write to `.codehub/scan.sarif`.
|
|
19
|
+
* 7. Ingest findings into the graph via `runIngestSarif`.
|
|
20
|
+
* 8. Exit with 0 when no HIGH+CRIT findings, 1 when any, 2 when a
|
|
21
|
+
* scanner returned non-zero or crashed.
|
|
22
|
+
*
|
|
23
|
+
* The --severity filter gates the exit code only; every finding is
|
|
24
|
+
* still written to SARIF and the graph.
|
|
25
|
+
*/
|
|
26
|
+
import { readFileSync } from "node:fs";
|
|
27
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
28
|
+
import { join, resolve } from "node:path";
|
|
29
|
+
import { applyBaselineState, applySuppressions, enrichWithFingerprints, loadSuppressions, SarifLogSchema, } from "@opencodehub/sarif";
|
|
30
|
+
import { ALL_SPECS, CHECKOV_SPEC, createDefaultWrappers, filterSpecsByProfile, HADOLINT_SPEC, P1_SPECS, PIP_AUDIT_SPEC, runScanners, SPECTRAL_SPEC, } from "@opencodehub/scanners";
|
|
31
|
+
import { openStore, resolveDbPath, resolveRepoMetaDir } from "@opencodehub/storage";
|
|
32
|
+
import { readRegistry } from "../registry.js";
|
|
33
|
+
import { runIngestSarif } from "./ingest-sarif.js";
|
|
34
|
+
const DEFAULT_SEVERITY_THRESHOLD = new Set(["HIGH", "CRITICAL", "error"]);
|
|
35
|
+
export async function runScan(path, opts = {}) {
|
|
36
|
+
const repoPath = await resolveRepoPath(path, opts);
|
|
37
|
+
const outputPath = resolve(opts.output ?? `${resolveRepoMetaDir(repoPath)}/scan.sarif`);
|
|
38
|
+
const profile = await readProjectProfile(repoPath);
|
|
39
|
+
const specs = selectScanners(profile, opts);
|
|
40
|
+
if (specs.length === 0) {
|
|
41
|
+
console.warn("codehub scan: no scanners selected — nothing to do.");
|
|
42
|
+
return {
|
|
43
|
+
repoPath,
|
|
44
|
+
outputPath,
|
|
45
|
+
runs: [],
|
|
46
|
+
totalFindings: 0,
|
|
47
|
+
bySeverity: {},
|
|
48
|
+
exitCode: 0,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
console.warn(`codehub scan: running ${specs.length} scanner(s): ${specs.map((s) => s.id).join(", ")}`);
|
|
52
|
+
const wrapperContext = await buildWrapperContext(repoPath, profile, specs);
|
|
53
|
+
const wrappers = createDefaultWrappers(specs, undefined, wrapperContext);
|
|
54
|
+
const runnerOpts = {
|
|
55
|
+
...(opts.concurrency !== undefined ? { concurrency: opts.concurrency } : {}),
|
|
56
|
+
...(opts.timeoutMs !== undefined ? { timeoutMs: opts.timeoutMs } : {}),
|
|
57
|
+
onProgress: (spec, status, note) => {
|
|
58
|
+
if (status === "error") {
|
|
59
|
+
console.warn(`codehub scan: ${spec.id} errored: ${note ?? ""}`);
|
|
60
|
+
}
|
|
61
|
+
else if (status === "skipped" && note) {
|
|
62
|
+
console.warn(`codehub scan: ${spec.id} skipped: ${note}`);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
console.warn(`codehub scan: ${spec.id} ${status}`);
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
const result = await runScanners(repoPath, wrappers, runnerOpts);
|
|
70
|
+
// Stamp `opencodehub/v1` + `primaryLocationLineHash` fingerprints on
|
|
71
|
+
// every result before anything else touches the log so downstream
|
|
72
|
+
// consumers (baseline diff, ingest-sarif, `list_findings_delta`) all
|
|
73
|
+
// read the same match keys.
|
|
74
|
+
const enriched = enrichWithFingerprints(result.sarif);
|
|
75
|
+
// Optional baseline diff: tag every result with
|
|
76
|
+
// `baselineState` so downstream consumers (scan output, ingest-sarif,
|
|
77
|
+
// verdict) can distinguish pre-existing debt from newly introduced
|
|
78
|
+
// findings. Results with baselineState === "unchanged" are suppressed
|
|
79
|
+
// from the severity-gate exit code below.
|
|
80
|
+
const baselineLog = await loadBaselineLog(opts.baseline);
|
|
81
|
+
const afterBaseline = baselineLog !== undefined ? applyBaselineState(enriched, baselineLog) : enriched;
|
|
82
|
+
// : tag suppressed findings from `.codehub/suppressions.yaml` +
|
|
83
|
+
// inline `codehub-suppress: <ruleId> <reason>` comments. Suppressed
|
|
84
|
+
// results still travel through SARIF and the graph; `codehub verdict`
|
|
85
|
+
// and the severity gate below treat them as non-blocking.
|
|
86
|
+
const finalSarif = applySuppressionsForRepo(repoPath, afterBaseline);
|
|
87
|
+
// Write merged SARIF to disk.
|
|
88
|
+
await mkdir(resolveRepoMetaDir(repoPath), { recursive: true });
|
|
89
|
+
await writeFile(outputPath, `${JSON.stringify(finalSarif, null, 2)}\n`, "utf8");
|
|
90
|
+
// Ingest into the graph (best effort — missing graph is non-fatal).
|
|
91
|
+
// Forward the already-resolved `repoPath` so the SARIF lands in the
|
|
92
|
+
// SCANNED repo's graph, not the operator's CWD. `runIngestSarif`
|
|
93
|
+
// accepts an absolute path in `opts.repo` as a registry-name fallback
|
|
94
|
+
// (`ingest-sarif.ts:351-352`), so this works for both `--repo NAME`
|
|
95
|
+
// and positional `<path>` invocations.
|
|
96
|
+
try {
|
|
97
|
+
const ingestOpts = { repo: opts.repo ?? repoPath };
|
|
98
|
+
if (opts.home !== undefined)
|
|
99
|
+
ingestOpts.home = opts.home;
|
|
100
|
+
await runIngestSarif(outputPath, ingestOpts);
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
104
|
+
console.warn(`codehub scan: ingest-sarif skipped: ${msg}`);
|
|
105
|
+
}
|
|
106
|
+
// Summarize. Suppressed findings AND baseline-unchanged
|
|
107
|
+
// findings are excluded from the severity-gate exit code but still
|
|
108
|
+
// counted in `totalFindings` so operators see the full footprint.
|
|
109
|
+
const bySeverity = {};
|
|
110
|
+
const bySeverityGated = {};
|
|
111
|
+
let totalFindings = 0;
|
|
112
|
+
let suppressedCount = 0;
|
|
113
|
+
let unchangedCount = 0;
|
|
114
|
+
for (const run of finalSarif.runs) {
|
|
115
|
+
const results = run.results ?? [];
|
|
116
|
+
for (const r of results) {
|
|
117
|
+
const level = r.level ?? "note";
|
|
118
|
+
bySeverity[level] = (bySeverity[level] ?? 0) + 1;
|
|
119
|
+
totalFindings += 1;
|
|
120
|
+
const suppArr = r.suppressions;
|
|
121
|
+
const suppressed = Array.isArray(suppArr) && suppArr.length > 0;
|
|
122
|
+
const state = r.baselineState;
|
|
123
|
+
const unchangedVsBaseline = state === "unchanged";
|
|
124
|
+
if (suppressed)
|
|
125
|
+
suppressedCount += 1;
|
|
126
|
+
if (unchangedVsBaseline)
|
|
127
|
+
unchangedCount += 1;
|
|
128
|
+
if (!suppressed && !unchangedVsBaseline) {
|
|
129
|
+
bySeverityGated[level] = (bySeverityGated[level] ?? 0) + 1;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const severityThreshold = resolveSeverityThreshold(opts.severity);
|
|
134
|
+
let exitCode = 0;
|
|
135
|
+
if (result.errored.length > 0) {
|
|
136
|
+
exitCode = 2;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
for (const [level, count] of Object.entries(bySeverityGated)) {
|
|
140
|
+
if (count > 0 && severityThreshold.has(level)) {
|
|
141
|
+
exitCode = 1;
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const runs = result.runs.map((r) => {
|
|
147
|
+
const findings = (r.sarif.runs[0]?.results ?? []).length;
|
|
148
|
+
return r.skipped !== undefined
|
|
149
|
+
? { scanner: r.spec.id, findings, skipped: r.skipped }
|
|
150
|
+
: { scanner: r.spec.id, findings };
|
|
151
|
+
});
|
|
152
|
+
const suppressedNote = suppressedCount > 0 ? ` (${suppressedCount} suppressed)` : "";
|
|
153
|
+
const baselineNote = baselineLog !== undefined ? ` (${unchangedCount} unchanged vs baseline)` : "";
|
|
154
|
+
console.warn(`codehub scan: wrote ${outputPath} — ${totalFindings} findings${baselineNote}${suppressedNote} across ${runs.length} scanner(s), exit=${exitCode}`);
|
|
155
|
+
return { repoPath, outputPath, runs, totalFindings, bySeverity, exitCode };
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Load `.codehub/suppressions.yaml` (if present) and apply both YAML rules
|
|
159
|
+
* and inline `codehub-suppress:` markers to the merged SARIF log. Missing
|
|
160
|
+
* files resolve silently; malformed files emit a warning through
|
|
161
|
+
* loadSuppressions but never abort the scan. Source files are read lazily
|
|
162
|
+
* through a memoized reader so the same file isn't slurped for every
|
|
163
|
+
* finding.
|
|
164
|
+
*/
|
|
165
|
+
function applySuppressionsForRepo(repoPath, log) {
|
|
166
|
+
const yamlPath = join(repoPath, ".codehub", "suppressions.yaml");
|
|
167
|
+
const loaded = loadSuppressions(yamlPath);
|
|
168
|
+
for (const w of loaded.warnings) {
|
|
169
|
+
console.warn(`codehub scan: ${w}`);
|
|
170
|
+
}
|
|
171
|
+
const sourceCache = new Map();
|
|
172
|
+
const readSource = (uri) => {
|
|
173
|
+
if (sourceCache.has(uri))
|
|
174
|
+
return sourceCache.get(uri);
|
|
175
|
+
let content;
|
|
176
|
+
try {
|
|
177
|
+
content = readFileSync(resolve(repoPath, uri), "utf8");
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
content = undefined;
|
|
181
|
+
}
|
|
182
|
+
sourceCache.set(uri, content);
|
|
183
|
+
return content;
|
|
184
|
+
};
|
|
185
|
+
return applySuppressions(log, loaded.rules, readSource);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Read the ProjectProfile node (if present) so we can gate scanners by
|
|
189
|
+
* detected languages, IaC types, and API contracts. If the graph is
|
|
190
|
+
* absent, every field is returned empty — falls back to the polyglot P1
|
|
191
|
+
* subset.
|
|
192
|
+
*/
|
|
193
|
+
export async function readProjectProfile(repoPath) {
|
|
194
|
+
const dbPath = resolveDbPath(repoPath);
|
|
195
|
+
try {
|
|
196
|
+
const composed = await openStore({ path: dbPath, backend: "auto", readOnly: true });
|
|
197
|
+
try {
|
|
198
|
+
await composed.graph.open();
|
|
199
|
+
// The single-row ProjectProfile lookup. `listNodesByKind` materializes
|
|
200
|
+
// a typed `ProjectProfileNode`, which already carries the typed
|
|
201
|
+
// `languages` / `iacTypes` / `apiContracts` arrays — no JSON parsing
|
|
202
|
+
// needed. The legacy SQL went through the wide-column `*_json`
|
|
203
|
+
// shape because the column encoder serialised them; the storage
|
|
204
|
+
// layer now hands back the rehydrated TS shape directly.
|
|
205
|
+
const rows = await composed.graph.listNodesByKind("ProjectProfile", { limit: 1 });
|
|
206
|
+
const row = rows[0];
|
|
207
|
+
if (!row)
|
|
208
|
+
return {};
|
|
209
|
+
return {
|
|
210
|
+
languages: row.languages,
|
|
211
|
+
iacTypes: row.iacTypes,
|
|
212
|
+
apiContracts: row.apiContracts,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
finally {
|
|
216
|
+
await composed.close();
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
return {};
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Exported for tests: apply --scanners / --with / profile gating to
|
|
225
|
+
* produce the final scanner list.
|
|
226
|
+
*/
|
|
227
|
+
export function selectScanners(profile, opts) {
|
|
228
|
+
const requested = opts.scanners;
|
|
229
|
+
const withList = opts.withScanners ?? [];
|
|
230
|
+
// --scanners=... overrides profile gating entirely. `--with` is
|
|
231
|
+
// additive either way.
|
|
232
|
+
if (requested !== undefined) {
|
|
233
|
+
const merged = new Set([...requested, ...withList]);
|
|
234
|
+
return ALL_SPECS.filter((s) => merged.has(s.id));
|
|
235
|
+
}
|
|
236
|
+
const gated = filterSpecsByProfile(ALL_SPECS, profile);
|
|
237
|
+
if (withList.length === 0)
|
|
238
|
+
return gated;
|
|
239
|
+
// --with adds scanners on top of profile gating (useful for forcing a
|
|
240
|
+
// P2 scanner to run even when the profile didn't flag the relevant
|
|
241
|
+
// IaC type, e.g. `--with trivy` on a repo with no Dockerfiles).
|
|
242
|
+
const byId = new Map(gated.map((s) => [s.id, s]));
|
|
243
|
+
for (const id of withList) {
|
|
244
|
+
const spec = ALL_SPECS.find((s) => s.id === id);
|
|
245
|
+
if (spec)
|
|
246
|
+
byId.set(id, spec);
|
|
247
|
+
}
|
|
248
|
+
return [...byId.values()];
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Build the per-scanner context passed to `createDefaultWrappers`. Only
|
|
252
|
+
* populates fields for scanners that are actually in `specs` — avoids
|
|
253
|
+
* wasted filesystem work.
|
|
254
|
+
*/
|
|
255
|
+
async function buildWrapperContext(repoPath, profile, specs) {
|
|
256
|
+
const ids = new Set(specs.map((s) => s.id));
|
|
257
|
+
const ctx = {};
|
|
258
|
+
if (ids.has(CHECKOV_SPEC.id)) {
|
|
259
|
+
ctx.checkov = { frameworks: profile.iacTypes ?? [] };
|
|
260
|
+
}
|
|
261
|
+
if (ids.has(HADOLINT_SPEC.id)) {
|
|
262
|
+
ctx.hadolint = { dockerfiles: await findDockerfiles(repoPath) };
|
|
263
|
+
}
|
|
264
|
+
if (ids.has(SPECTRAL_SPEC.id)) {
|
|
265
|
+
ctx.spectral = { contractFiles: await findOpenApiFiles(repoPath) };
|
|
266
|
+
}
|
|
267
|
+
if (ids.has(PIP_AUDIT_SPEC.id)) {
|
|
268
|
+
ctx.pipAudit = { requirementsPath: "requirements.txt" };
|
|
269
|
+
}
|
|
270
|
+
return ctx;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Walk the repo for Dockerfile* files. Bounded to one breadth-first pass
|
|
274
|
+
* with a per-directory file cap so huge repos don't explode; the typical
|
|
275
|
+
* case has ≤5 Dockerfiles.
|
|
276
|
+
*/
|
|
277
|
+
async function findDockerfiles(repoPath) {
|
|
278
|
+
const { readdir } = await import("node:fs/promises");
|
|
279
|
+
const { join, relative } = await import("node:path");
|
|
280
|
+
const MAX_FILES = 256;
|
|
281
|
+
const out = [];
|
|
282
|
+
const queue = [repoPath];
|
|
283
|
+
while (queue.length > 0 && out.length < MAX_FILES) {
|
|
284
|
+
const dir = queue.shift();
|
|
285
|
+
if (dir === undefined)
|
|
286
|
+
break;
|
|
287
|
+
let entries;
|
|
288
|
+
try {
|
|
289
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
for (const e of entries) {
|
|
295
|
+
if (e.name === "node_modules" || e.name === ".git" || e.name.startsWith(".codehub")) {
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
const abs = join(dir, e.name);
|
|
299
|
+
if (e.isDirectory()) {
|
|
300
|
+
queue.push(abs);
|
|
301
|
+
}
|
|
302
|
+
else if (e.isFile() && /^Dockerfile(\..+)?$/.test(e.name)) {
|
|
303
|
+
out.push(relative(repoPath, abs));
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return out;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Locate OpenAPI / Swagger / AsyncAPI / Arazzo contracts. Mirrors the
|
|
311
|
+
* ProjectProfile API-contract detector's matching rules but just pulls
|
|
312
|
+
* the paths (no content sniff — good enough for Spectral invocation).
|
|
313
|
+
*/
|
|
314
|
+
async function findOpenApiFiles(repoPath) {
|
|
315
|
+
const { readdir } = await import("node:fs/promises");
|
|
316
|
+
const { join, relative } = await import("node:path");
|
|
317
|
+
const MAX_FILES = 64;
|
|
318
|
+
const RE = /^(openapi|swagger|asyncapi|arazzo)\.(ya?ml|json)$/i;
|
|
319
|
+
const out = [];
|
|
320
|
+
const queue = [repoPath];
|
|
321
|
+
while (queue.length > 0 && out.length < MAX_FILES) {
|
|
322
|
+
const dir = queue.shift();
|
|
323
|
+
if (dir === undefined)
|
|
324
|
+
break;
|
|
325
|
+
let entries;
|
|
326
|
+
try {
|
|
327
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
328
|
+
}
|
|
329
|
+
catch {
|
|
330
|
+
continue;
|
|
331
|
+
}
|
|
332
|
+
for (const e of entries) {
|
|
333
|
+
if (e.name === "node_modules" || e.name === ".git" || e.name.startsWith(".codehub")) {
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
const abs = join(dir, e.name);
|
|
337
|
+
if (e.isDirectory()) {
|
|
338
|
+
queue.push(abs);
|
|
339
|
+
}
|
|
340
|
+
else if (e.isFile() && RE.test(e.name)) {
|
|
341
|
+
out.push(relative(repoPath, abs));
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
return out;
|
|
346
|
+
}
|
|
347
|
+
function resolveSeverityThreshold(input) {
|
|
348
|
+
if (input === undefined || input.length === 0)
|
|
349
|
+
return DEFAULT_SEVERITY_THRESHOLD;
|
|
350
|
+
const out = new Set();
|
|
351
|
+
for (const s of input) {
|
|
352
|
+
const trimmed = s.trim();
|
|
353
|
+
if (trimmed.length === 0)
|
|
354
|
+
continue;
|
|
355
|
+
out.add(trimmed);
|
|
356
|
+
// Translate common aliases so users can write either SARIF levels or
|
|
357
|
+
// severity words.
|
|
358
|
+
if (trimmed === "HIGH")
|
|
359
|
+
out.add("error");
|
|
360
|
+
if (trimmed === "CRITICAL")
|
|
361
|
+
out.add("error");
|
|
362
|
+
if (trimmed === "MEDIUM")
|
|
363
|
+
out.add("warning");
|
|
364
|
+
if (trimmed === "LOW")
|
|
365
|
+
out.add("note");
|
|
366
|
+
}
|
|
367
|
+
return out;
|
|
368
|
+
}
|
|
369
|
+
async function resolveRepoPath(path, opts) {
|
|
370
|
+
if (opts.repo !== undefined) {
|
|
371
|
+
const registryOpts = opts.home !== undefined ? { home: opts.home } : {};
|
|
372
|
+
const registry = await readRegistry(registryOpts);
|
|
373
|
+
const hit = registry[opts.repo];
|
|
374
|
+
if (hit)
|
|
375
|
+
return resolve(hit.path);
|
|
376
|
+
return resolve(opts.repo);
|
|
377
|
+
}
|
|
378
|
+
return resolve(path);
|
|
379
|
+
}
|
|
380
|
+
/** Helper exposed for tests: parse a SARIF file from disk. */
|
|
381
|
+
export async function readSarifFile(path) {
|
|
382
|
+
const raw = await readFile(path, "utf8");
|
|
383
|
+
return JSON.parse(raw);
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Read + validate a baseline SARIF log. Returns undefined when no
|
|
387
|
+
* baseline was requested. Throws when the path was given but the file
|
|
388
|
+
* is missing or corrupt — a bad baseline should fail loudly, not silently
|
|
389
|
+
* skip the diff.
|
|
390
|
+
*/
|
|
391
|
+
async function loadBaselineLog(path) {
|
|
392
|
+
if (path === undefined)
|
|
393
|
+
return undefined;
|
|
394
|
+
const resolved = resolve(path);
|
|
395
|
+
const raw = await readFile(resolved, "utf8");
|
|
396
|
+
const parsed = JSON.parse(raw);
|
|
397
|
+
const result = SarifLogSchema.safeParse(parsed);
|
|
398
|
+
if (!result.success) {
|
|
399
|
+
throw new Error(`codehub scan: baseline ${resolved} is not a valid SARIF 2.1.0 log: ${result.error.message}`);
|
|
400
|
+
}
|
|
401
|
+
return result.data;
|
|
402
|
+
}
|
|
403
|
+
// `P1_SPECS` re-export preserves the import shape for any existing consumers
|
|
404
|
+
// that have been reading it via the CLI barrel. New callers should import
|
|
405
|
+
// from `@opencodehub/scanners` directly.
|
|
406
|
+
export { P1_SPECS };
|
|
407
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codehub setup` — detects installed editors and writes an MCP server entry
|
|
3
|
+
* for `codehub` into each one's config file.
|
|
4
|
+
*
|
|
5
|
+
* We deliberately do *not* probe each editor to confirm it is "installed" —
|
|
6
|
+
* writing to a config path is idempotent and safe, and a user can run setup
|
|
7
|
+
* before installing an editor. Instead we:
|
|
8
|
+
* 1. Determine the invocation (`codehub mcp`) with optional Windows wrap.
|
|
9
|
+
* 2. For each selected editor, read the existing config, back it up, and
|
|
10
|
+
* atomically write the merged version that adds or replaces the
|
|
11
|
+
* `codehub` entry.
|
|
12
|
+
*
|
|
13
|
+
* Filesystem access goes through the `FsApi` seam so tests can run against an
|
|
14
|
+
* in-memory implementation.
|
|
15
|
+
*/
|
|
16
|
+
import { runSetupCobolProleap, type SetupCobolProleapOptions, type SetupCobolProleapResult } from "../cobol-proleap-setup.js";
|
|
17
|
+
import { type EditorId, type McpInvocation } from "../editors/index.js";
|
|
18
|
+
import { type DownloadEmbedderOptions, type DownloadEmbedderResult } from "../embedder-downloader.js";
|
|
19
|
+
import { type InstallScipResult, type FetchFn as ScipFetchFn, type ScipTool } from "../scip-downloader.js";
|
|
20
|
+
export type { SetupCobolProleapOptions, SetupCobolProleapResult };
|
|
21
|
+
export { runSetupCobolProleap };
|
|
22
|
+
/**
|
|
23
|
+
* Filesystem seam. Tests supply an in-memory implementation.
|
|
24
|
+
* Every operation is async to keep the seam uniform.
|
|
25
|
+
*/
|
|
26
|
+
export interface FsApi {
|
|
27
|
+
readFile(path: string): Promise<string>;
|
|
28
|
+
writeFileAtomic(path: string, contents: string): Promise<void>;
|
|
29
|
+
copyFile(src: string, dest: string): Promise<void>;
|
|
30
|
+
mkdir(path: string): Promise<void>;
|
|
31
|
+
exists(path: string): Promise<boolean>;
|
|
32
|
+
readdir?(path: string): Promise<readonly string[]>;
|
|
33
|
+
rename?(src: string, dest: string): Promise<void>;
|
|
34
|
+
rm?(path: string, opts?: {
|
|
35
|
+
recursive?: boolean;
|
|
36
|
+
force?: boolean;
|
|
37
|
+
}): Promise<void>;
|
|
38
|
+
statIsDirectory?(path: string): Promise<boolean>;
|
|
39
|
+
}
|
|
40
|
+
/** Default implementation that calls through to real `fs`. */
|
|
41
|
+
export declare const DEFAULT_FS: FsApi;
|
|
42
|
+
export interface SetupOptions {
|
|
43
|
+
/** Which editors to write. Defaults to all 5. */
|
|
44
|
+
readonly editors?: readonly EditorId[];
|
|
45
|
+
/** Overwrite an existing `codehub` entry without prompting. Always true for MVP. */
|
|
46
|
+
readonly force?: boolean;
|
|
47
|
+
/** Restore the `.bak` file onto the config, if present. */
|
|
48
|
+
readonly undo?: boolean;
|
|
49
|
+
/** Absolute path to the project. Used by per-project writers. */
|
|
50
|
+
readonly projectRoot?: string;
|
|
51
|
+
/** Override the user's home dir. Used by global writers. */
|
|
52
|
+
readonly home?: string;
|
|
53
|
+
/** Explicit MCP invocation override. Default: `codehub mcp`. */
|
|
54
|
+
readonly invocation?: McpInvocation;
|
|
55
|
+
/** FS seam. Defaults to real filesystem. */
|
|
56
|
+
readonly fs?: FsApi;
|
|
57
|
+
/** Override `process.platform`. Tests use this to force Windows paths. */
|
|
58
|
+
readonly platform?: NodeJS.Platform;
|
|
59
|
+
/** Structured logger. Defaults to `console.log`/`console.error`. */
|
|
60
|
+
readonly log?: (message: string) => void;
|
|
61
|
+
readonly warn?: (message: string) => void;
|
|
62
|
+
}
|
|
63
|
+
export interface SetupResult {
|
|
64
|
+
readonly editor: EditorId;
|
|
65
|
+
readonly configPath: string;
|
|
66
|
+
readonly action: "wrote" | "restored" | "skipped" | "unchanged";
|
|
67
|
+
readonly backupPath?: string;
|
|
68
|
+
}
|
|
69
|
+
/** Public entry point. Returns per-editor results for programmatic callers. */
|
|
70
|
+
export declare function runSetup(opts?: SetupOptions): Promise<readonly SetupResult[]>;
|
|
71
|
+
/**
|
|
72
|
+
* Options for `codehub setup --embeddings`. Mirrors the downloader API but
|
|
73
|
+
* allows the CLI `log`/`warn` sinks to be overridden for tests.
|
|
74
|
+
*/
|
|
75
|
+
export interface SetupEmbeddingsOptions {
|
|
76
|
+
/** Variant to install. Defaults to `fp32` (~596 MB). */
|
|
77
|
+
readonly variant?: "fp32" | "int8";
|
|
78
|
+
/** Custom model directory. Defaults to `~/.codehub/models/gte-modernbert-base/<variant>/`. */
|
|
79
|
+
readonly modelDir?: string;
|
|
80
|
+
/** Re-download even if files already match their SHA256 pin. */
|
|
81
|
+
readonly force?: boolean;
|
|
82
|
+
/** Dependency-inject fetch for tests. */
|
|
83
|
+
readonly fetchImpl?: DownloadEmbedderOptions["fetchImpl"];
|
|
84
|
+
/** Progress sink. Defaults to no-op. */
|
|
85
|
+
readonly onProgress?: DownloadEmbedderOptions["onProgress"];
|
|
86
|
+
/** Structured logger. Defaults to `console.warn`. */
|
|
87
|
+
readonly log?: (message: string) => void;
|
|
88
|
+
readonly warn?: (message: string) => void;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Public entry point for `codehub setup --embeddings`.
|
|
92
|
+
*
|
|
93
|
+
* Downloads the five pinned gte-modernbert-base files into the target dir with
|
|
94
|
+
* streaming SHA256 verification and atomic rename. Returns the downloader
|
|
95
|
+
* summary so programmatic callers can assert on byte counts and locations.
|
|
96
|
+
*/
|
|
97
|
+
export declare function runSetupEmbeddings(opts?: SetupEmbeddingsOptions): Promise<DownloadEmbedderResult>;
|
|
98
|
+
/**
|
|
99
|
+
* Options for `codehub setup --scip=<tool>` and `--scip=all`.
|
|
100
|
+
*
|
|
101
|
+
* Each call installs one or more SCIP adapter binaries (clang, ruby, dotnet,
|
|
102
|
+
* kotlin) into `~/.codehub/bin/` via the SHA256-pinned `scip-downloader`.
|
|
103
|
+
* scip-dotnet defers to `dotnet tool install --global scip-dotnet` and
|
|
104
|
+
* requires a .NET SDK 8+ on PATH.
|
|
105
|
+
*/
|
|
106
|
+
export interface SetupScipOptions {
|
|
107
|
+
/** Tool name (`"clang" | "ruby" | "dotnet" | "kotlin"`) or `"all"`. Required. */
|
|
108
|
+
readonly tool: ScipTool | "all";
|
|
109
|
+
/** Override the install dir. Defaults to `~/.codehub/bin/`. */
|
|
110
|
+
readonly destDir?: string;
|
|
111
|
+
/** Re-download even if the on-disk binary already matches the pin. */
|
|
112
|
+
readonly force?: boolean;
|
|
113
|
+
/** Dependency-inject fetch (tests). */
|
|
114
|
+
readonly fetchImpl?: ScipFetchFn;
|
|
115
|
+
/** Bypass the placeholder-hash refusal (for adapter first-install smoke tests). */
|
|
116
|
+
readonly allowPlaceholder?: boolean;
|
|
117
|
+
/** Structured logger. Defaults to `console.warn`. */
|
|
118
|
+
readonly log?: (message: string) => void;
|
|
119
|
+
readonly warn?: (message: string) => void;
|
|
120
|
+
}
|
|
121
|
+
export interface SetupScipResult {
|
|
122
|
+
readonly installed: readonly InstallScipResult[];
|
|
123
|
+
readonly failed: readonly {
|
|
124
|
+
tool: ScipTool;
|
|
125
|
+
error: Error;
|
|
126
|
+
}[];
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Public entry point for `codehub setup --scip=<tool>` / `--scip=all`.
|
|
130
|
+
*
|
|
131
|
+
* Dispatches to {@link installScipTool} for one tool, or
|
|
132
|
+
* {@link installAllScipTools} for the full set. Never throws — every error is
|
|
133
|
+
* surfaced on `stderr` via `warn` and collected into the `failed` array so
|
|
134
|
+
* `--scip=all` completes the surviving tools instead of short-circuiting on
|
|
135
|
+
* the first missing .NET SDK.
|
|
136
|
+
*/
|
|
137
|
+
export declare function runSetupScip(opts: SetupScipOptions): Promise<SetupScipResult>;
|
|
138
|
+
/**
|
|
139
|
+
* Parse the CLI `--scip=<value>` flag. Accepts a tool name or the literal
|
|
140
|
+
* `"all"`. Throws on anything else so typos surface instead of silently
|
|
141
|
+
* defaulting.
|
|
142
|
+
*/
|
|
143
|
+
export declare function parseScipFlag(raw: string): ScipTool | "all";
|
|
144
|
+
/**
|
|
145
|
+
* Options for `codehub setup --plugin`. Copies the static `plugins/opencodehub/`
|
|
146
|
+
* tree shipped with this repo into `<home>/.claude/plugins/opencodehub/` so
|
|
147
|
+
* Claude Code picks up the five slash commands, the `code-analyst` subagent,
|
|
148
|
+
* and the PostToolUse auto-reindex hook.
|
|
149
|
+
*
|
|
150
|
+
* Atomic: files are copied into a sibling `<target>.tmp-<pid>` dir first, then
|
|
151
|
+
* the final `<target>` is removed and the temp dir renamed into place. A
|
|
152
|
+
* partial crash leaves the previous install intact.
|
|
153
|
+
*/
|
|
154
|
+
export interface SetupPluginOptions {
|
|
155
|
+
/** Override the user's home dir. Defaults to `os.homedir()`. */
|
|
156
|
+
readonly home?: string;
|
|
157
|
+
/** Override the plugin source directory. Defaults to the in-repo `plugins/opencodehub/`. */
|
|
158
|
+
readonly sourceDir?: string;
|
|
159
|
+
/** FS seam. Defaults to real filesystem. */
|
|
160
|
+
readonly fs?: FsApi;
|
|
161
|
+
/** Structured logger. Defaults to `console.warn`. */
|
|
162
|
+
readonly log?: (message: string) => void;
|
|
163
|
+
readonly warn?: (message: string) => void;
|
|
164
|
+
}
|
|
165
|
+
export interface SetupPluginResult {
|
|
166
|
+
readonly sourceDir: string;
|
|
167
|
+
readonly targetDir: string;
|
|
168
|
+
readonly filesCopied: number;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Public entry point for `codehub setup --plugin`.
|
|
172
|
+
*
|
|
173
|
+
* Walks `sourceDir` and mirrors it into `<home>/.claude/plugins/opencodehub/`.
|
|
174
|
+
* Both the temp dir and the final rename go through `FsApi` so tests can run
|
|
175
|
+
* against an in-memory implementation.
|
|
176
|
+
*/
|
|
177
|
+
export declare function runSetupPlugin(opts?: SetupPluginOptions): Promise<SetupPluginResult>;
|
|
178
|
+
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"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"}
|