geopilot 0.0.0-stage → 0.0.1-bootstrap.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 +72 -2
- package/dist/agent/install.d.ts +23 -0
- package/dist/agent/install.js +75 -0
- package/dist/agent/install.js.map +1 -0
- package/dist/cache/runs.d.ts +18 -0
- package/dist/cache/runs.js +91 -0
- package/dist/cache/runs.js.map +1 -0
- package/dist/cli/args.d.ts +20 -0
- package/dist/cli/args.js +116 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/commands/agent.d.ts +2 -0
- package/dist/cli/commands/agent.js +48 -0
- package/dist/cli/commands/agent.js.map +1 -0
- package/dist/cli/commands/fix.d.ts +2 -0
- package/dist/cli/commands/fix.js +284 -0
- package/dist/cli/commands/fix.js.map +1 -0
- package/dist/cli/commands/init.d.ts +2 -0
- package/dist/cli/commands/init.js +62 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/insights.d.ts +17 -0
- package/dist/cli/commands/insights.js +143 -0
- package/dist/cli/commands/insights.js.map +1 -0
- package/dist/cli/commands/rules.d.ts +5 -0
- package/dist/cli/commands/rules.js +86 -0
- package/dist/cli/commands/rules.js.map +1 -0
- package/dist/cli/commands/scan.d.ts +14 -0
- package/dist/cli/commands/scan.js +127 -0
- package/dist/cli/commands/scan.js.map +1 -0
- package/dist/cli/commands-list.d.ts +6 -0
- package/dist/cli/commands-list.js +15 -0
- package/dist/cli/commands-list.js.map +1 -0
- package/dist/cli/context.d.ts +26 -0
- package/dist/cli/context.js +108 -0
- package/dist/cli/context.js.map +1 -0
- package/dist/cli/io.d.ts +16 -0
- package/dist/cli/io.js +28 -0
- package/dist/cli/io.js.map +1 -0
- package/dist/cli/main.d.ts +15 -0
- package/dist/cli/main.js +118 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/collect/crawl.d.ts +51 -0
- package/dist/collect/crawl.js +187 -0
- package/dist/collect/crawl.js.map +1 -0
- package/dist/config/config.d.ts +86 -0
- package/dist/config/config.js +396 -0
- package/dist/config/config.js.map +1 -0
- package/dist/core/errors.d.ts +20 -0
- package/dist/core/errors.js +32 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/hash.d.ts +7 -0
- package/dist/core/hash.js +28 -0
- package/dist/core/hash.js.map +1 -0
- package/dist/core/redact.d.ts +3 -0
- package/dist/core/redact.js +23 -0
- package/dist/core/redact.js.map +1 -0
- package/dist/core/tty.d.ts +12 -0
- package/dist/core/tty.js +33 -0
- package/dist/core/tty.js.map +1 -0
- package/dist/core/version.d.ts +6 -0
- package/dist/core/version.js +10 -0
- package/dist/core/version.js.map +1 -0
- package/dist/fix/apply.d.ts +119 -0
- package/dist/fix/apply.js +334 -0
- package/dist/fix/apply.js.map +1 -0
- package/dist/fix/diff.d.ts +1 -0
- package/dist/fix/diff.js +35 -0
- package/dist/fix/diff.js.map +1 -0
- package/dist/fix/plan.d.ts +42 -0
- package/dist/fix/plan.js +385 -0
- package/dist/fix/plan.js.map +1 -0
- package/dist/fix/serve.d.ts +13 -0
- package/dist/fix/serve.js +112 -0
- package/dist/fix/serve.js.map +1 -0
- package/dist/fix/variants.d.ts +13 -0
- package/dist/fix/variants.js +8 -0
- package/dist/fix/variants.js.map +1 -0
- package/dist/frameworks/ast.d.ts +84 -0
- package/dist/frameworks/ast.js +231 -0
- package/dist/frameworks/ast.js.map +1 -0
- package/dist/frameworks/nextjs-app/analyze.d.ts +92 -0
- package/dist/frameworks/nextjs-app/analyze.js +350 -0
- package/dist/frameworks/nextjs-app/analyze.js.map +1 -0
- package/dist/frameworks/static/analyze.d.ts +18 -0
- package/dist/frameworks/static/analyze.js +66 -0
- package/dist/frameworks/static/analyze.js.map +1 -0
- package/dist/html/parse.d.ts +50 -0
- package/dist/html/parse.js +205 -0
- package/dist/html/parse.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/insights/validate.d.ts +74 -0
- package/dist/insights/validate.js +213 -0
- package/dist/insights/validate.js.map +1 -0
- package/dist/net/address.d.ts +10 -0
- package/dist/net/address.js +116 -0
- package/dist/net/address.js.map +1 -0
- package/dist/net/fetch.d.ts +53 -0
- package/dist/net/fetch.js +281 -0
- package/dist/net/fetch.js.map +1 -0
- package/dist/repo/detect.d.ts +3 -0
- package/dist/repo/detect.js +92 -0
- package/dist/repo/detect.js.map +1 -0
- package/dist/repo/reader.d.ts +12 -0
- package/dist/repo/reader.js +97 -0
- package/dist/repo/reader.js.map +1 -0
- package/dist/report/render.d.ts +20 -0
- package/dist/report/render.js +176 -0
- package/dist/report/render.js.map +1 -0
- package/dist/robots/crawlers.d.ts +10 -0
- package/dist/robots/crawlers.js +20 -0
- package/dist/robots/crawlers.js.map +1 -0
- package/dist/robots/robots.d.ts +33 -0
- package/dist/robots/robots.js +133 -0
- package/dist/robots/robots.js.map +1 -0
- package/dist/rules/catalogue.d.ts +43 -0
- package/dist/rules/catalogue.js +361 -0
- package/dist/rules/catalogue.js.map +1 -0
- package/dist/rules/context.d.ts +36 -0
- package/dist/rules/context.js +129 -0
- package/dist/rules/context.js.map +1 -0
- package/dist/rules/evaluate.d.ts +11 -0
- package/dist/rules/evaluate.js +1070 -0
- package/dist/rules/evaluate.js.map +1 -0
- package/dist/rules/finalize.d.ts +34 -0
- package/dist/rules/finalize.js +93 -0
- package/dist/rules/finalize.js.map +1 -0
- package/dist/scan.d.ts +27 -0
- package/dist/scan.js +147 -0
- package/dist/scan.js.map +1 -0
- package/dist/scoring/compare.d.ts +21 -0
- package/dist/scoring/compare.js +47 -0
- package/dist/scoring/compare.js.map +1 -0
- package/dist/scoring/score.d.ts +21 -0
- package/dist/scoring/score.js +112 -0
- package/dist/scoring/score.js.map +1 -0
- package/dist/sitemap/sitemap.d.ts +10 -0
- package/dist/sitemap/sitemap.js +48 -0
- package/dist/sitemap/sitemap.js.map +1 -0
- package/dist/types.d.ts +155 -0
- package/dist/types.js +13 -0
- package/dist/types.js.map +1 -0
- package/hosts/claude-project/.claude/agents/geopilot-explainer.md +36 -0
- package/hosts/claude-project/.claude/agents/geopilot-fixer.md +42 -0
- package/hosts/claude-project/.claude/agents/geopilot-investigator.md +45 -0
- package/hosts/claude-project/.claude/agents/geopilot-reviewer.md +41 -0
- package/hosts/claude-project/.claude/agents/geopilot-scanner.md +47 -0
- package/hosts/claude-project/.claude/skills/geo/SKILL.md +95 -0
- package/hosts/claude-project/.claude/skills/geo/references/frameworks.md +20 -0
- package/hosts/claude-project/.claude/skills/geo/references/insight-contract.md +42 -0
- package/hosts/claude-project/.claude/skills/geo/references/safety.md +30 -0
- package/hosts/claude-project/.claude/skills/geo/references/workflow-explain.md +8 -0
- package/hosts/claude-project/.claude/skills/geo/references/workflow-fix.md +20 -0
- package/hosts/claude-project/.claude/skills/geo/references/workflow-init.md +6 -0
- package/hosts/claude-project/.claude/skills/geo/references/workflow-insights.md +13 -0
- package/hosts/claude-project/.claude/skills/geo/references/workflow-plan.md +13 -0
- package/hosts/claude-project/.claude/skills/geo/references/workflow-review.md +8 -0
- package/hosts/claude-project/.claude/skills/geo/references/workflow-scan.md +18 -0
- package/hosts/claude-project/.claude/skills/geo/schemas/insights.schema.json +255 -0
- package/hosts/claude-project/.claude/skills/geo/scripts/geo.ps1 +11 -0
- package/hosts/claude-project/.claude/skills/geo/scripts/geo.sh +11 -0
- package/hosts/claude-project/.claude/skills/geopilot-explain/SKILL.md +9 -0
- package/hosts/claude-project/.claude/skills/geopilot-fix/SKILL.md +12 -0
- package/hosts/claude-project/.claude/skills/geopilot-init/SKILL.md +15 -0
- package/hosts/claude-project/.claude/skills/geopilot-insights/SKILL.md +11 -0
- package/hosts/claude-project/.claude/skills/geopilot-review/SKILL.md +11 -0
- package/hosts/claude-project/.claude/skills/geopilot-scan/SKILL.md +11 -0
- package/hosts/geopilot/.claude-plugin/plugin.json +22 -0
- package/hosts/geopilot/README.md +25 -0
- package/hosts/geopilot/agents/explainer.agent.md +36 -0
- package/hosts/geopilot/agents/fixer.agent.md +42 -0
- package/hosts/geopilot/agents/investigator.agent.md +45 -0
- package/hosts/geopilot/agents/reviewer.agent.md +41 -0
- package/hosts/geopilot/agents/scanner.agent.md +47 -0
- package/hosts/geopilot/assets/icon.png +0 -0
- package/hosts/geopilot/skills/explain/SKILL.md +9 -0
- package/hosts/geopilot/skills/fix/SKILL.md +12 -0
- package/hosts/geopilot/skills/geo/SKILL.md +95 -0
- package/hosts/geopilot/skills/geo/references/frameworks.md +20 -0
- package/hosts/geopilot/skills/geo/references/insight-contract.md +42 -0
- package/hosts/geopilot/skills/geo/references/safety.md +30 -0
- package/hosts/geopilot/skills/geo/references/workflow-explain.md +8 -0
- package/hosts/geopilot/skills/geo/references/workflow-fix.md +20 -0
- package/hosts/geopilot/skills/geo/references/workflow-init.md +6 -0
- package/hosts/geopilot/skills/geo/references/workflow-insights.md +13 -0
- package/hosts/geopilot/skills/geo/references/workflow-plan.md +13 -0
- package/hosts/geopilot/skills/geo/references/workflow-review.md +8 -0
- package/hosts/geopilot/skills/geo/references/workflow-scan.md +18 -0
- package/hosts/geopilot/skills/geo/schemas/insights.schema.json +255 -0
- package/hosts/geopilot/skills/geo/scripts/geo.ps1 +11 -0
- package/hosts/geopilot/skills/geo/scripts/geo.sh +11 -0
- package/hosts/geopilot/skills/init/SKILL.md +15 -0
- package/hosts/geopilot/skills/insights/SKILL.md +11 -0
- package/hosts/geopilot/skills/review/SKILL.md +11 -0
- package/hosts/geopilot/skills/scan/SKILL.md +11 -0
- package/hosts/opencode/.opencode/agents/geopilot-explainer.md +39 -0
- package/hosts/opencode/.opencode/agents/geopilot-fixer.md +45 -0
- package/hosts/opencode/.opencode/agents/geopilot-investigator.md +48 -0
- package/hosts/opencode/.opencode/agents/geopilot-reviewer.md +44 -0
- package/hosts/opencode/.opencode/agents/geopilot-scanner.md +50 -0
- package/hosts/opencode/.opencode/commands/geopilot-explain.md +8 -0
- package/hosts/opencode/.opencode/commands/geopilot-fix.md +10 -0
- package/hosts/opencode/.opencode/commands/geopilot-init.md +12 -0
- package/hosts/opencode/.opencode/commands/geopilot-insights.md +10 -0
- package/hosts/opencode/.opencode/commands/geopilot-review.md +10 -0
- package/hosts/opencode/.opencode/commands/geopilot-scan.md +10 -0
- package/hosts/opencode/.opencode/skills/geo/SKILL.md +95 -0
- package/hosts/opencode/.opencode/skills/geo/references/frameworks.md +20 -0
- package/hosts/opencode/.opencode/skills/geo/references/insight-contract.md +42 -0
- package/hosts/opencode/.opencode/skills/geo/references/safety.md +30 -0
- package/hosts/opencode/.opencode/skills/geo/references/workflow-explain.md +8 -0
- package/hosts/opencode/.opencode/skills/geo/references/workflow-fix.md +20 -0
- package/hosts/opencode/.opencode/skills/geo/references/workflow-init.md +6 -0
- package/hosts/opencode/.opencode/skills/geo/references/workflow-insights.md +13 -0
- package/hosts/opencode/.opencode/skills/geo/references/workflow-plan.md +13 -0
- package/hosts/opencode/.opencode/skills/geo/references/workflow-review.md +8 -0
- package/hosts/opencode/.opencode/skills/geo/references/workflow-scan.md +18 -0
- package/hosts/opencode/.opencode/skills/geo/schemas/insights.schema.json +255 -0
- package/hosts/opencode/.opencode/skills/geo/scripts/geo.ps1 +11 -0
- package/hosts/opencode/.opencode/skills/geo/scripts/geo.sh +11 -0
- package/package.json +65 -4
- package/schemas/config-v1.json +392 -0
- package/schemas/insights-v1.json +255 -0
- package/schemas/merged-v1.json +71 -0
- package/schemas/report-v1.json +836 -0
- package/skill/geo/SKILL.md +95 -0
- package/skill/geo/references/frameworks.md +20 -0
- package/skill/geo/references/insight-contract.md +42 -0
- package/skill/geo/references/safety.md +30 -0
- package/skill/geo/references/workflow-explain.md +8 -0
- package/skill/geo/references/workflow-fix.md +20 -0
- package/skill/geo/references/workflow-init.md +6 -0
- package/skill/geo/references/workflow-insights.md +13 -0
- package/skill/geo/references/workflow-plan.md +13 -0
- package/skill/geo/references/workflow-review.md +8 -0
- package/skill/geo/references/workflow-scan.md +18 -0
- package/skill/geo/schemas/insights.schema.json +255 -0
- package/skill/geo/scripts/geo.ps1 +11 -0
- package/skill/geo/scripts/geo.sh +11 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { EXIT, usage } from "../../core/errors.js";
|
|
4
|
+
import { canonicalJson } from "../../core/hash.js";
|
|
5
|
+
import { loadRun } from "../../cache/runs.js";
|
|
6
|
+
import { statusLabel, validateReferences, validateSchema } from "../../insights/validate.js";
|
|
7
|
+
import { renderMarkdown, sortedFindings } from "../../report/render.js";
|
|
8
|
+
import { renderPretty, renderJson, FORMATS } from "../../report/render.js";
|
|
9
|
+
import { GLOBAL_FLAGS, INSIGHTS_FLAGS, parseArgs } from "../args.js";
|
|
10
|
+
import { cacheFor, gitRoot, loadFor, resolveCwd } from "../context.js";
|
|
11
|
+
function readJson(path) {
|
|
12
|
+
if (!existsSync(path))
|
|
13
|
+
throw usage(`${path} does not exist`);
|
|
14
|
+
try {
|
|
15
|
+
return JSON.parse(readFileSync(path, 'utf8'));
|
|
16
|
+
}
|
|
17
|
+
catch (e) {
|
|
18
|
+
throw usage(`${path} is not valid JSON: ${e.message}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function validateFile(file, runId, cwd, deps, p) {
|
|
22
|
+
const { doc, errors } = validateSchema(readJson(file));
|
|
23
|
+
if (!doc)
|
|
24
|
+
return { doc: null, result: { schemaErrors: errors, results: [], evidenceAvailable: false }, run: null };
|
|
25
|
+
const loaded = loadFor(cwd, p, deps.env);
|
|
26
|
+
const root = gitRoot(cwd);
|
|
27
|
+
const cache = cacheFor(root, cwd, loaded, deps.env);
|
|
28
|
+
const id = runId ?? doc.basedOn.runId;
|
|
29
|
+
let run = null;
|
|
30
|
+
try {
|
|
31
|
+
run = loadRun(cache, id);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
run = null;
|
|
35
|
+
}
|
|
36
|
+
return { doc, result: validateReferences(doc, run, root), run };
|
|
37
|
+
}
|
|
38
|
+
export async function insightsCommand(argv, deps) {
|
|
39
|
+
const p = parseArgs(argv, [...GLOBAL_FLAGS, ...INSIGHTS_FLAGS]);
|
|
40
|
+
if (p.positionals[0] !== 'validate')
|
|
41
|
+
throw usage('insights takes validate <file> [--run <id>]');
|
|
42
|
+
const file = p.positionals[1];
|
|
43
|
+
if (!file)
|
|
44
|
+
throw usage('insights validate needs a file, usually .geo/insights.json');
|
|
45
|
+
const cwd = resolveCwd(p, deps);
|
|
46
|
+
const { result } = validateFile(resolve(cwd, file), p.str.get('run'), cwd, deps, p);
|
|
47
|
+
const json = (p.multi.get('format') ?? []).includes('json');
|
|
48
|
+
if (json)
|
|
49
|
+
deps.io.out(canonicalJson(result));
|
|
50
|
+
else {
|
|
51
|
+
if (result.schemaErrors.length > 0)
|
|
52
|
+
deps.io.out(`L1 schema: invalid\n ${result.schemaErrors.join('\n ')}\n`);
|
|
53
|
+
else {
|
|
54
|
+
deps.io.out('L1 schema: valid\n');
|
|
55
|
+
if (!result.evidenceAvailable)
|
|
56
|
+
deps.io.out('L2 references: no retained run evidence (was the scan run with --no-cache?). URL and finding references are unchecked.\n');
|
|
57
|
+
for (const r of result.results)
|
|
58
|
+
deps.io.out(` ${r.id.padEnd(16)} ${r.kind.padEnd(14)} ${statusLabel(r.status)}${r.reasons.length ? `: ${r.reasons.join('; ')}` : ''}\n`);
|
|
59
|
+
deps.io.out('L3 semantic quality is a human/model evaluation; it never affects readiness or gates.\n');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (result.schemaErrors.length > 0 || result.results.some((r) => r.status === 'reference_invalid'))
|
|
63
|
+
return EXIT.gate;
|
|
64
|
+
if (!result.evidenceAvailable || result.results.some((r) => r.status === 'unchecked'))
|
|
65
|
+
return EXIT.incomplete;
|
|
66
|
+
return EXIT.ok;
|
|
67
|
+
}
|
|
68
|
+
function renderMerged(m) {
|
|
69
|
+
const lines = [renderMarkdown(m.report), '## Agent recommendations', ''];
|
|
70
|
+
const status = new Map(m.validation?.results.map((r) => [r.id, r]) ?? []);
|
|
71
|
+
const show = (kind) => {
|
|
72
|
+
const items = (m.insights?.insights ?? []).filter((i) => i.kind === kind && status.get(i.id)?.status !== 'stale' && status.get(i.id)?.status !== 'duplicate_exact');
|
|
73
|
+
if (items.length === 0)
|
|
74
|
+
lines.push('None.');
|
|
75
|
+
for (const i of items)
|
|
76
|
+
lines.push(`- **${i.title}** (${i.confidence} confidence; ${statusLabel(status.get(i.id)?.status ?? 'unchecked')}): ${i.description} — _${i.suggestedAction}_`);
|
|
77
|
+
lines.push('');
|
|
78
|
+
};
|
|
79
|
+
show('recommendation');
|
|
80
|
+
lines.push('## Hypotheses to validate', '');
|
|
81
|
+
show('hypothesis');
|
|
82
|
+
lines.push('_Agent output is not an engine result. "Evidence resolved" means the cited files and URLs exist as cited, not that the recommendation is correct._', '');
|
|
83
|
+
return lines.join('\n');
|
|
84
|
+
}
|
|
85
|
+
export async function reportCommand(argv, deps) {
|
|
86
|
+
const p = parseArgs(argv, [...GLOBAL_FLAGS, ...INSIGHTS_FLAGS]);
|
|
87
|
+
const sub = p.positionals[0];
|
|
88
|
+
const cwd = resolveCwd(p, deps);
|
|
89
|
+
const output = (p.multi.get('output') ?? [])[0];
|
|
90
|
+
const format = ((p.multi.get('format') ?? [])[0] ?? (output?.endsWith('.json') ? 'json' : 'markdown'));
|
|
91
|
+
if (!FORMATS.includes(format))
|
|
92
|
+
throw usage(`unknown --format ${format}`);
|
|
93
|
+
const write = (text) => {
|
|
94
|
+
if (output)
|
|
95
|
+
writeFileSync(resolve(cwd, output), text);
|
|
96
|
+
else
|
|
97
|
+
deps.io.out(text);
|
|
98
|
+
};
|
|
99
|
+
if (sub === 'convert') {
|
|
100
|
+
const file = p.positionals[1];
|
|
101
|
+
if (!file)
|
|
102
|
+
throw usage('report convert needs a saved report.json');
|
|
103
|
+
const report = readJson(resolve(cwd, file));
|
|
104
|
+
if (report.schemaVersion !== 'geo-report/v1')
|
|
105
|
+
throw usage(`${file} is not a geo-report/v1 document`);
|
|
106
|
+
write(format === 'json' ? renderJson(report) : format === 'markdown' ? renderMarkdown(report) : renderPretty(report, deps.io.color));
|
|
107
|
+
return EXIT.ok;
|
|
108
|
+
}
|
|
109
|
+
if (sub === 'merge') {
|
|
110
|
+
const reportFile = p.positionals[1];
|
|
111
|
+
const insightsFile = p.positionals[2];
|
|
112
|
+
if (!reportFile)
|
|
113
|
+
throw usage('report merge needs <report.json> [insights.json]');
|
|
114
|
+
const report = readJson(resolve(cwd, reportFile));
|
|
115
|
+
if (report.schemaVersion !== 'geo-report/v1')
|
|
116
|
+
throw usage(`${reportFile} is not a geo-report/v1 document`);
|
|
117
|
+
let doc = null;
|
|
118
|
+
let validation = null;
|
|
119
|
+
if (insightsFile) {
|
|
120
|
+
const v = validateFile(resolve(cwd, insightsFile), p.str.get('run') ?? report.run.id, cwd, deps, p);
|
|
121
|
+
doc = v.doc;
|
|
122
|
+
validation = v.result;
|
|
123
|
+
if (!doc)
|
|
124
|
+
throw usage(`${insightsFile} fails L1 schema validation: ${v.result.schemaErrors[0]}`);
|
|
125
|
+
}
|
|
126
|
+
const merged = {
|
|
127
|
+
schemaVersion: 'geo-merged/v1',
|
|
128
|
+
report,
|
|
129
|
+
insights: doc,
|
|
130
|
+
validation,
|
|
131
|
+
sections: {
|
|
132
|
+
verifiedEngineFindings: sortedFindings(report).filter((x) => x.finding.evidenceQuality !== 'inferred').map((x) => x.finding.fingerprint),
|
|
133
|
+
agentRecommendations: (doc?.insights ?? []).filter((i) => i.kind === 'recommendation').map((i) => i.id),
|
|
134
|
+
hypothesesToValidate: (doc?.insights ?? []).filter((i) => i.kind === 'hypothesis').map((i) => i.id),
|
|
135
|
+
},
|
|
136
|
+
disclaimer: report.disclaimer,
|
|
137
|
+
};
|
|
138
|
+
write(format === 'json' ? canonicalJson(merged) : renderMerged(merged));
|
|
139
|
+
return EXIT.ok;
|
|
140
|
+
}
|
|
141
|
+
throw usage('report takes merge or convert');
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=insights.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insights.js","sourceRoot":"","sources":["../../../src/cli/commands/insights.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type RuleMeta } from '../../rules/catalogue.ts';
|
|
2
|
+
import type { Deps } from '../context.ts';
|
|
3
|
+
export declare function explainText(meta: RuleMeta, p: Deps['io']['color']): string;
|
|
4
|
+
export declare function explainCommand(argv: readonly string[], deps: Deps): Promise<number>;
|
|
5
|
+
export declare function rulesCommand(argv: readonly string[], deps: Deps): Promise<number>;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { EXIT, usage } from "../../core/errors.js";
|
|
2
|
+
import { canonicalJson } from "../../core/hash.js";
|
|
3
|
+
import { findRule, RETIRED, RULES, ruleDocsUrl } from "../../rules/catalogue.js";
|
|
4
|
+
import { VARIANTS } from "../../fix/plan.js";
|
|
5
|
+
import { GLOBAL_FLAGS, parseArgs, RULES_FLAGS } from "../args.js";
|
|
6
|
+
export function explainText(meta, p) {
|
|
7
|
+
const lines = [];
|
|
8
|
+
lines.push(`${p.brand(p.bold(meta.id))} ${p.bold(meta.title)}`);
|
|
9
|
+
lines.push('');
|
|
10
|
+
lines.push(meta.purpose);
|
|
11
|
+
lines.push('');
|
|
12
|
+
lines.push(`${p.dim('Evidence class')} ${meta.evidenceClass}${meta.scored ? ` ${p.dim('weight')} ${meta.weight}` : ` ${p.dim('unscored')}`} ${p.dim('scope')} ${meta.scope} ${p.dim('subject')} ${meta.subject === 'site' ? 'site' : 'route group'}`);
|
|
13
|
+
lines.push(`${p.dim('Default severity')} ${meta.severity} ${p.dim('lifecycle')} ${meta.lifecycle}`);
|
|
14
|
+
if (meta.subChecks.length > 0) {
|
|
15
|
+
lines.push('');
|
|
16
|
+
lines.push(p.dim('Sub-checks (a rule never passes on a partial set of these)'));
|
|
17
|
+
for (const s of meta.subChecks)
|
|
18
|
+
lines.push(` ${s.id.padEnd(20)} ${p.dim(`[${s.scope}]`.padEnd(7))} ${s.description}`);
|
|
19
|
+
}
|
|
20
|
+
if (meta.preconditions.length > 0) {
|
|
21
|
+
lines.push('');
|
|
22
|
+
lines.push(p.dim('Preconditions'));
|
|
23
|
+
for (const x of meta.preconditions)
|
|
24
|
+
lines.push(` · ${x}`);
|
|
25
|
+
}
|
|
26
|
+
lines.push('');
|
|
27
|
+
lines.push(`${p.dim('Fix class')} ${meta.fixClass}`);
|
|
28
|
+
for (const v of meta.fixVariants) {
|
|
29
|
+
const spec = VARIANTS[v];
|
|
30
|
+
lines.push(spec ? ` ${v} ${spec.title} (${spec.class}, requires ${spec.required})` : ` ${v} Phase 2`);
|
|
31
|
+
}
|
|
32
|
+
lines.push('');
|
|
33
|
+
lines.push(`${p.dim('Remediation')} ${meta.remediation}`);
|
|
34
|
+
if (meta.falsePositives.length > 0) {
|
|
35
|
+
lines.push('');
|
|
36
|
+
lines.push(p.dim('Known false positives'));
|
|
37
|
+
for (const x of meta.falsePositives)
|
|
38
|
+
lines.push(` · ${x}`);
|
|
39
|
+
}
|
|
40
|
+
if (meta.blockerCap)
|
|
41
|
+
lines.push(`\n${p.dim('Readiness cap')} capped at 40 when direct evidence shows: ${meta.blockerCap}`);
|
|
42
|
+
lines.push('');
|
|
43
|
+
lines.push(p.dim('References'));
|
|
44
|
+
for (const r of meta.references)
|
|
45
|
+
lines.push(` · ${r.title} (${r.kind}) ${p.dim(r.url)}`);
|
|
46
|
+
lines.push('');
|
|
47
|
+
lines.push(`${p.dim('Docs')} ${ruleDocsUrl(meta.id)}`);
|
|
48
|
+
return `${lines.join('\n')}\n`;
|
|
49
|
+
}
|
|
50
|
+
export async function explainCommand(argv, deps) {
|
|
51
|
+
const p = parseArgs(argv, GLOBAL_FLAGS);
|
|
52
|
+
const id = p.positionals[0];
|
|
53
|
+
if (!id)
|
|
54
|
+
throw usage('explain needs a rule id, e.g. geopilot explain GEO-012');
|
|
55
|
+
const meta = findRule(id);
|
|
56
|
+
if (!meta) {
|
|
57
|
+
const retired = RETIRED.find((r) => r.id === id.toUpperCase());
|
|
58
|
+
if (retired) {
|
|
59
|
+
deps.io.out(`${retired.id} (${retired.title}) is retired. GEO does not score content-format mandates; an agent may still raise grounded content insights.\n`);
|
|
60
|
+
return EXIT.ok;
|
|
61
|
+
}
|
|
62
|
+
throw usage(`unknown rule ${id}`, 'Run geopilot rules for the catalogue.');
|
|
63
|
+
}
|
|
64
|
+
if ((p.multi.get('format') ?? []).includes('json'))
|
|
65
|
+
deps.io.out(canonicalJson(meta));
|
|
66
|
+
else
|
|
67
|
+
deps.io.out(explainText(meta, deps.io.color));
|
|
68
|
+
return EXIT.ok;
|
|
69
|
+
}
|
|
70
|
+
export async function rulesCommand(argv, deps) {
|
|
71
|
+
const p = parseArgs(argv, [...GLOBAL_FLAGS, ...RULES_FLAGS]);
|
|
72
|
+
const list = p.bool.has('all') ? RULES : RULES.filter((r) => r.lifecycle !== 'informational');
|
|
73
|
+
if (p.bool.has('json') || (p.multi.get('format') ?? []).includes('json')) {
|
|
74
|
+
deps.io.out(canonicalJson({ rules: list, retired: p.bool.has('all') ? RETIRED : [] }));
|
|
75
|
+
return EXIT.ok;
|
|
76
|
+
}
|
|
77
|
+
const c = deps.io.color;
|
|
78
|
+
for (const r of list) {
|
|
79
|
+
deps.io.out(`${c.brand(r.id)} ${r.evidenceClass} ${r.scored ? `w${r.weight}` : ' '} ${r.title} ${c.dim(r.scope)}\n`);
|
|
80
|
+
}
|
|
81
|
+
if (p.bool.has('all'))
|
|
82
|
+
for (const r of RETIRED)
|
|
83
|
+
deps.io.out(`${c.dim(`${r.id} retired ${r.title}`)}\n`);
|
|
84
|
+
return EXIT.ok;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../../src/cli/commands/rules.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type GeoConfig } from '../../config/config.ts';
|
|
2
|
+
import { type ScanResult } from '../../scan.ts';
|
|
3
|
+
import { type Parsed } from '../args.ts';
|
|
4
|
+
import { type Deps } from '../context.ts';
|
|
5
|
+
export interface ScanInvocation {
|
|
6
|
+
readonly result: ScanResult;
|
|
7
|
+
readonly cache: string | null;
|
|
8
|
+
readonly cwd: string;
|
|
9
|
+
readonly repoPath: string | null;
|
|
10
|
+
readonly config: GeoConfig;
|
|
11
|
+
}
|
|
12
|
+
/** Shared by `scan` and `fix`: resolve targets, load config, run, cache. */
|
|
13
|
+
export declare function runScan(p: Parsed, deps: Deps, forceRepo?: boolean): Promise<ScanInvocation>;
|
|
14
|
+
export declare function scanCommand(argv: readonly string[], deps: Deps): Promise<number>;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { existsSync, statSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { EXIT, usage } from "../../core/errors.js";
|
|
4
|
+
import { printableConfig } from "../../config/config.js";
|
|
5
|
+
import { saveRun } from "../../cache/runs.js";
|
|
6
|
+
import { findRule } from "../../rules/catalogue.js";
|
|
7
|
+
import { scan } from "../../scan.js";
|
|
8
|
+
import { intFlag, parseArgs, GLOBAL_FLAGS, SCAN_FLAGS } from "../args.js";
|
|
9
|
+
import { cacheFor, emit, loadFor, resolveCwd } from "../context.js";
|
|
10
|
+
const SEVERITY_RANK = { high: 3, medium: 2, low: 1, info: 0 };
|
|
11
|
+
function ruleList(values, flag) {
|
|
12
|
+
if (!values)
|
|
13
|
+
return undefined;
|
|
14
|
+
return values.flatMap((v) => v.split(',')).map((id) => {
|
|
15
|
+
const meta = findRule(id.trim());
|
|
16
|
+
if (!meta)
|
|
17
|
+
throw usage(`--${flag} ${id}: unknown rule id`, 'Run geopilot rules for the catalogue.');
|
|
18
|
+
return meta.id;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function normaliseUrlArg(u) {
|
|
22
|
+
try {
|
|
23
|
+
const url = new URL(u);
|
|
24
|
+
if (url.protocol !== 'http:' && url.protocol !== 'https:')
|
|
25
|
+
throw new Error('scheme');
|
|
26
|
+
return url.href;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
throw usage(`${u} is not an http(s) URL`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Shared by `scan` and `fix`: resolve targets, load config, run, cache. */
|
|
33
|
+
export async function runScan(p, deps, forceRepo = false) {
|
|
34
|
+
const cwd = resolveCwd(p, deps);
|
|
35
|
+
const positional = p.positionals[0];
|
|
36
|
+
const urls = [...(p.multi.get('url') ?? [])].map(normaliseUrlArg);
|
|
37
|
+
let repoPath = null;
|
|
38
|
+
if (positional && /^https?:\/\//i.test(positional))
|
|
39
|
+
urls.unshift(normaliseUrlArg(positional));
|
|
40
|
+
else if (positional) {
|
|
41
|
+
repoPath = resolve(cwd, positional);
|
|
42
|
+
if (!existsSync(repoPath) || !statSync(repoPath).isDirectory())
|
|
43
|
+
throw usage(`${positional} is not a directory or an http(s) URL`);
|
|
44
|
+
}
|
|
45
|
+
else if (urls.length === 0 || forceRepo)
|
|
46
|
+
repoPath = cwd;
|
|
47
|
+
if (p.positionals.length > 1)
|
|
48
|
+
throw usage('scan takes one path or URL; pass more URLs with --url');
|
|
49
|
+
if (p.bool.has('ignore-robots') && urls.length === 0)
|
|
50
|
+
throw usage('--ignore-robots only applies to an explicitly named URL target');
|
|
51
|
+
const loaded = loadFor(repoPath ?? cwd, p, deps.env);
|
|
52
|
+
let config = loaded.config;
|
|
53
|
+
const render = p.str.get('render');
|
|
54
|
+
if (render !== undefined) {
|
|
55
|
+
if (!['auto', 'always', 'never'].includes(render))
|
|
56
|
+
throw usage('--render must be auto, always or never');
|
|
57
|
+
config = { ...config, crawl: { ...config.crawl, render: render } };
|
|
58
|
+
}
|
|
59
|
+
const routes = p.multi.get('routes');
|
|
60
|
+
if (routes)
|
|
61
|
+
config = { ...config, routes: { ...config.routes, include: routes.flatMap((r) => r.split(',')) } };
|
|
62
|
+
if (p.str.has('baseline'))
|
|
63
|
+
throw usage('--baseline is not available in this release', 'Baselines ship in Phase 3.');
|
|
64
|
+
const result = await scan({
|
|
65
|
+
repoPath,
|
|
66
|
+
urls,
|
|
67
|
+
config,
|
|
68
|
+
configHash: loaded.hash,
|
|
69
|
+
...(intFlag(p, 'max-pages', 1, 200) === undefined ? {} : { maxPages: intFlag(p, 'max-pages', 1, 200) }),
|
|
70
|
+
...(intFlag(p, 'max-depth', 0, 10) === undefined ? {} : { maxDepth: intFlag(p, 'max-depth', 0, 10) }),
|
|
71
|
+
followExternal: p.bool.has('follow-external'),
|
|
72
|
+
ignoreRobots: p.bool.has('ignore-robots'),
|
|
73
|
+
...(ruleList(p.multi.get('rule'), 'rule') ? { only: ruleList(p.multi.get('rule'), 'rule') } : {}),
|
|
74
|
+
...(ruleList(p.multi.get('skip-rule'), 'skip-rule') ? { skip: ruleList(p.multi.get('skip-rule'), 'skip-rule') } : {}),
|
|
75
|
+
...(deps.fetcher ? { fetcher: deps.fetcher } : {}),
|
|
76
|
+
...(deps.now ? { now: deps.now } : {}),
|
|
77
|
+
});
|
|
78
|
+
let cache = null;
|
|
79
|
+
if (!p.bool.has('no-cache')) {
|
|
80
|
+
cache = cacheFor(repoPath, cwd, loaded, deps.env);
|
|
81
|
+
saveRun(cache, result.report, result.snapshots);
|
|
82
|
+
}
|
|
83
|
+
return { result, cache, cwd, repoPath, config };
|
|
84
|
+
}
|
|
85
|
+
export async function scanCommand(argv, deps) {
|
|
86
|
+
const p = parseArgs(argv, [...GLOBAL_FLAGS, ...SCAN_FLAGS]);
|
|
87
|
+
if (p.bool.has('print-config')) {
|
|
88
|
+
const cwd = resolveCwd(p, deps);
|
|
89
|
+
deps.io.out(printableConfig(loadFor(cwd, p, deps.env).config));
|
|
90
|
+
return EXIT.ok;
|
|
91
|
+
}
|
|
92
|
+
const failOn = p.str.get('fail-on');
|
|
93
|
+
if (failOn !== undefined && !(failOn in SEVERITY_RANK))
|
|
94
|
+
throw usage('--fail-on must be high, medium, low or info');
|
|
95
|
+
const minReadiness = intFlag(p, 'min-readiness', 0, 100);
|
|
96
|
+
const { result, cache, cwd, config } = await runScan(p, deps);
|
|
97
|
+
const r = result.report;
|
|
98
|
+
emit(r, p, deps, cwd);
|
|
99
|
+
if (cache && !p.bool.has('quiet'))
|
|
100
|
+
deps.io.err(deps.io.errColor.dim(`run ${r.run.id} cached in ${cache}\n`));
|
|
101
|
+
const gateFailOn = failOn ?? config.thresholds.failOn;
|
|
102
|
+
const gateMin = minReadiness ?? config.thresholds.minReadiness;
|
|
103
|
+
let code = EXIT.ok;
|
|
104
|
+
if (gateFailOn) {
|
|
105
|
+
const hits = r.evaluations.flatMap((e) => e.findings).filter((f) => f.evidenceQuality !== 'inferred' && SEVERITY_RANK[f.severity] >= SEVERITY_RANK[gateFailOn]);
|
|
106
|
+
if (hits.length > 0) {
|
|
107
|
+
deps.io.err(`gate: ${hits.length} finding(s) at or above ${gateFailOn}\n`);
|
|
108
|
+
code = EXIT.gate;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (gateMin !== null && gateMin !== undefined) {
|
|
112
|
+
if (r.readiness.value === null || r.readiness.display === 'insufficient_evidence') {
|
|
113
|
+
deps.io.err(`gate: readiness is unavailable (insufficient evidence), so --min-readiness ${gateMin} cannot pass\n`);
|
|
114
|
+
code = EXIT.gate;
|
|
115
|
+
}
|
|
116
|
+
else if (r.readiness.value < gateMin) {
|
|
117
|
+
deps.io.err(`gate: readiness ${Math.round(r.readiness.value)} is below ${gateMin}\n`);
|
|
118
|
+
code = EXIT.gate;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (code === EXIT.ok && p.bool.has('fail-on-incomplete') && (r.assessmentScope.assessment === 'incomplete' || r.coverage < config.thresholds.minCoverage)) {
|
|
122
|
+
deps.io.err(`gate: assessment is ${r.assessmentScope.assessment} with ${Math.round(r.coverage)}% coverage (minimum ${config.thresholds.minCoverage}%)\n`);
|
|
123
|
+
code = EXIT.incomplete;
|
|
124
|
+
}
|
|
125
|
+
return code;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../../src/cli/commands/scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// The command table, shared by --help and the documentation site.
|
|
2
|
+
export const COMMANDS = [
|
|
3
|
+
{ name: 'scan', summary: 'Audit a URL, a repository, or both', usage: 'scan [path|url] [--url <u>...] [--max-pages n] [--max-depth n] [--render auto|always|never] [--rule id] [--skip-rule id] [--fail-on sev] [--min-readiness n] [--fail-on-incomplete] [--ignore-robots] [--follow-external]' },
|
|
4
|
+
{ name: 'explain', summary: 'Explain one rule: evidence, sub-checks, fixes, references', usage: 'explain <ruleId>' },
|
|
5
|
+
{ name: 'rules', summary: 'List the rule catalogue', usage: 'rules [--all] [--json]' },
|
|
6
|
+
{ name: 'fix', summary: 'Dry-run, apply, verify or roll back closed-list fixes', usage: 'fix [path] [--rule id] [--apply [--approve <fixId>...]] [--verify <runId>] [--rollback <runId>] [--verify-cmd "<cmd>"] [--serve] [--allow-dirty] [--url <u>]' },
|
|
7
|
+
{ name: 'init', summary: 'Preview and write geo.config.json', usage: 'init [--origin <url>] [--language <tag>] [--yes] [--force]' },
|
|
8
|
+
{ name: 'agent', summary: 'Install or check the portable agent skill', usage: 'agent install --host claude-code [--yes] | agent install --host agents-md --write-agents-md | agent status' },
|
|
9
|
+
{ name: 'insights', summary: 'Validate an agent insights file (L1 schema, L2 references)', usage: 'insights validate <file> [--run <id>]' },
|
|
10
|
+
{ name: 'report', summary: 'Merge insights into a report, or convert a saved report', usage: 'report merge <report.json> [insights.json] [--output f] | report convert <report.json> --format markdown' },
|
|
11
|
+
{ name: 'review', summary: 'Diff-aware assessment', usage: 'review [--base <ref>|--staged|--pre-push]', phase: 'Phase 3' },
|
|
12
|
+
{ name: 'baseline', summary: 'Fingerprint baselines', usage: 'baseline create|update|show', phase: 'Phase 3' },
|
|
13
|
+
{ name: 'hook', summary: 'Opt-in pre-push hook', usage: 'hook install|uninstall|status', phase: 'Phase 3' },
|
|
14
|
+
];
|
|
15
|
+
//# sourceMappingURL=commands-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands-list.js","sourceRoot":"","sources":["../../src/cli/commands-list.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,CAAC,MAAM,QAAQ,GAAoH;IACvI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,oCAAoC,EAAE,KAAK,EAAE,2NAA2N,EAAE;IACnS,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,2DAA2D,EAAE,KAAK,EAAE,kBAAkB,EAAE;IACpH,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,yBAAyB,EAAE,KAAK,EAAE,wBAAwB,EAAE;IACtF,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,uDAAuD,EAAE,KAAK,EAAE,8JAA8J,EAAE;IACxP,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,mCAAmC,EAAE,KAAK,EAAE,4DAA4D,EAAE;IACnI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,2CAA2C,EAAE,KAAK,EAAE,4GAA4G,EAAE;IAC5L,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,4DAA4D,EAAE,KAAK,EAAE,uCAAuC,EAAE;IAC3I,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,yDAAyD,EAAE,KAAK,EAAE,0GAA0G,EAAE;IACzM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,uBAAuB,EAAE,KAAK,EAAE,2CAA2C,EAAE,KAAK,EAAE,SAAS,EAAE;IAC1H,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,uBAAuB,EAAE,KAAK,EAAE,6BAA6B,EAAE,KAAK,EAAE,SAAS,EAAE;IAC9G,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,EAAE,KAAK,EAAE,+BAA+B,EAAE,KAAK,EAAE,SAAS,EAAE;CAC5G,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type LoadedConfig } from '../config/config.ts';
|
|
2
|
+
import type { Fetcher } from '../collect/crawl.ts';
|
|
3
|
+
import { type Format } from '../report/render.ts';
|
|
4
|
+
import type { Report } from '../types.ts';
|
|
5
|
+
import type { Io } from './io.ts';
|
|
6
|
+
import type { Parsed } from './args.ts';
|
|
7
|
+
export interface Deps {
|
|
8
|
+
readonly io: Io;
|
|
9
|
+
readonly cwd: string;
|
|
10
|
+
readonly env: NodeJS.ProcessEnv;
|
|
11
|
+
readonly fetcher?: Fetcher;
|
|
12
|
+
readonly now?: () => Date;
|
|
13
|
+
}
|
|
14
|
+
export declare function gitRoot(dir: string): string | null;
|
|
15
|
+
export declare function currentBranch(dir: string): string | null;
|
|
16
|
+
export declare function defaultBranch(dir: string): string | null;
|
|
17
|
+
export declare function dirtyFiles(dir: string, files: readonly string[]): string[];
|
|
18
|
+
export declare function resolveCwd(p: Parsed, deps: Deps): string;
|
|
19
|
+
export declare function loadFor(dir: string, p: Parsed, env: NodeJS.ProcessEnv): LoadedConfig;
|
|
20
|
+
export declare function cacheFor(repoPath: string | null, cwd: string, loaded: LoadedConfig, env: NodeJS.ProcessEnv): string;
|
|
21
|
+
export declare function parseFormats(p: Parsed): {
|
|
22
|
+
format: Format;
|
|
23
|
+
output: string | null;
|
|
24
|
+
}[];
|
|
25
|
+
export declare function emit(report: Report, p: Parsed, deps: Deps, cwd: string): void;
|
|
26
|
+
export declare function requireRepo(dir: string): void;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { existsSync, statSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
import { loadConfig } from "../config/config.js";
|
|
5
|
+
import { GeoError, usage } from "../core/errors.js";
|
|
6
|
+
import { cacheRoot } from "../cache/runs.js";
|
|
7
|
+
import { FORMATS, render } from "../report/render.js";
|
|
8
|
+
export function gitRoot(dir) {
|
|
9
|
+
try {
|
|
10
|
+
return execFileSync('git', ['rev-parse', '--show-toplevel'], { cwd: dir, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim() || null;
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function currentBranch(dir) {
|
|
17
|
+
try {
|
|
18
|
+
return execFileSync('git', ['branch', '--show-current'], { cwd: dir, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim() || null;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function defaultBranch(dir) {
|
|
25
|
+
try {
|
|
26
|
+
const ref = execFileSync('git', ['symbolic-ref', '--quiet', 'refs/remotes/origin/HEAD'], { cwd: dir, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
|
|
27
|
+
return ref.replace(/^refs\/remotes\/origin\//, '') || null;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export function dirtyFiles(dir, files) {
|
|
34
|
+
if (files.length === 0)
|
|
35
|
+
return [];
|
|
36
|
+
try {
|
|
37
|
+
const out = execFileSync('git', ['status', '--porcelain', '--', ...files], { cwd: dir, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
|
|
38
|
+
return out.split('\n').filter(Boolean).map((l) => l.slice(3));
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export function resolveCwd(p, deps) {
|
|
45
|
+
const c = p.str.get('cwd');
|
|
46
|
+
const dir = c ? resolve(deps.cwd, c) : deps.cwd;
|
|
47
|
+
if (!existsSync(dir) || !statSync(dir).isDirectory())
|
|
48
|
+
throw usage(`--cwd ${dir} is not a directory`);
|
|
49
|
+
return dir;
|
|
50
|
+
}
|
|
51
|
+
export function loadFor(dir, p, env) {
|
|
52
|
+
return loadConfig(dir, gitRoot(dir), p.str.get('config') ?? null, env);
|
|
53
|
+
}
|
|
54
|
+
export function cacheFor(repoPath, cwd, loaded, env) {
|
|
55
|
+
if (repoPath)
|
|
56
|
+
return cacheRoot(gitRoot(repoPath) ?? repoPath, env);
|
|
57
|
+
if (loaded.files.length > 0 || gitRoot(cwd))
|
|
58
|
+
return cacheRoot(gitRoot(cwd) ?? cwd, env);
|
|
59
|
+
return cacheRoot(null, env);
|
|
60
|
+
}
|
|
61
|
+
function formatFromPath(path) {
|
|
62
|
+
if (path.endsWith('.json'))
|
|
63
|
+
return 'json';
|
|
64
|
+
if (path.endsWith('.md') || path.endsWith('.markdown'))
|
|
65
|
+
return 'markdown';
|
|
66
|
+
if (path.endsWith('.txt'))
|
|
67
|
+
return 'pretty';
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
export function parseFormats(p) {
|
|
71
|
+
const formats = p.multi.get('format') ?? [];
|
|
72
|
+
const outputs = p.multi.get('output') ?? [];
|
|
73
|
+
for (const f of formats) {
|
|
74
|
+
if (f === 'sarif' || f === 'github')
|
|
75
|
+
throw usage(`--format ${f} is not available in this release`, 'SARIF and GitHub annotations ship with the Phase 3 GitHub Action. Use json, markdown or pretty.');
|
|
76
|
+
if (!FORMATS.includes(f))
|
|
77
|
+
throw usage(`unknown --format ${f}`, `Use one of ${FORMATS.join(', ')}.`);
|
|
78
|
+
}
|
|
79
|
+
const pairs = [];
|
|
80
|
+
const n = Math.max(formats.length, outputs.length);
|
|
81
|
+
for (let i = 0; i < n; i++) {
|
|
82
|
+
const output = outputs[i] ?? null;
|
|
83
|
+
const format = formats[i] ?? (output ? formatFromPath(output) : null) ?? 'pretty';
|
|
84
|
+
pairs.push({ format, output });
|
|
85
|
+
}
|
|
86
|
+
if (pairs.length === 0)
|
|
87
|
+
pairs.push({ format: 'pretty', output: null });
|
|
88
|
+
if (pairs.filter((x) => x.output === null).length > 1)
|
|
89
|
+
throw usage('only one format can go to stdout; pair the others with --output');
|
|
90
|
+
return pairs;
|
|
91
|
+
}
|
|
92
|
+
export function emit(report, p, deps, cwd) {
|
|
93
|
+
for (const { format, output } of parseFormats(p)) {
|
|
94
|
+
const text = render(report, format, deps.io.color);
|
|
95
|
+
if (output) {
|
|
96
|
+
writeFileSync(resolve(cwd, output), format === 'pretty' ? render(report, 'pretty', { brand: (s) => s, red: (s) => s, green: (s) => s, yellow: (s) => s, dim: (s) => s, bold: (s) => s }) : text);
|
|
97
|
+
if (!p.bool.has('quiet'))
|
|
98
|
+
deps.io.err(`wrote ${format} report to ${output}\n`);
|
|
99
|
+
}
|
|
100
|
+
else if (!p.bool.has('quiet') || format !== 'pretty')
|
|
101
|
+
deps.io.out(text);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
export function requireRepo(dir) {
|
|
105
|
+
if (!existsSync(dir))
|
|
106
|
+
throw new GeoError('usage', `${dir} does not exist`);
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/cli/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAqB,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EAAE,OAAO,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAanE,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;IACnJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,gBAAgB,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;IAC/I,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,cAAc,EAAE,SAAS,EAAE,0BAA0B,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACrK,OAAO,GAAG,CAAC,OAAO,CAAC,0BAA0B,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,KAAwB;IAC9D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;QAChJ,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,CAAS,EAAE,IAAU;IAC9C,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC3B,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;IAChD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;QAAE,MAAM,KAAK,CAAC,SAAS,GAAG,qBAAqB,CAAC,CAAC;IACrG,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,GAAW,EAAE,CAAS,EAAE,GAAsB;IACpE,OAAO,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE,GAAG,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,QAAuB,EAAE,GAAW,EAAE,MAAoB,EAAE,GAAsB;IACzG,IAAI,QAAQ;QAAE,OAAO,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,EAAE,GAAG,CAAC,CAAC;IACnE,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC;IACxF,OAAO,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,cAAc,CAAC,IAAY;IAClC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,MAAM,CAAC;IAC1C,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;QAAE,OAAO,UAAU,CAAC;IAC1E,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC3C,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,CAAS;IACpC,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC5C,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC5C,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,QAAQ;YAAE,MAAM,KAAK,CAAC,YAAY,CAAC,mCAAmC,EAAE,iGAAiG,CAAC,CAAC;QACtM,IAAI,CAAE,OAA6B,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,MAAM,KAAK,CAAC,oBAAoB,CAAC,EAAE,EAAE,cAAc,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7H,CAAC;IACD,MAAM,KAAK,GAAgD,EAAE,CAAC;IAC9D,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACnD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QAClC,MAAM,MAAM,GAAI,OAAO,CAAC,CAAC,CAAwB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC;QAC1G,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACvE,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACtI,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,MAAc,EAAE,CAAS,EAAE,IAAU,EAAE,GAAW;IACrE,KAAK,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;QACnD,IAAI,MAAM,EAAE,CAAC;YACX,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACjM,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;gBAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,MAAM,cAAc,MAAM,IAAI,CAAC,CAAC;QACjF,CAAC;aAAM,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,MAAM,KAAK,QAAQ;YAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,GAAG,GAAG,iBAAiB,CAAC,CAAC;AAC7E,CAAC"}
|
package/dist/cli/io.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type Palette } from '../core/tty.ts';
|
|
2
|
+
export interface Io {
|
|
3
|
+
out(text: string): void;
|
|
4
|
+
err(text: string): void;
|
|
5
|
+
readonly interactive: boolean;
|
|
6
|
+
readonly color: Palette;
|
|
7
|
+
readonly errColor: Palette;
|
|
8
|
+
confirm(question: string): Promise<boolean>;
|
|
9
|
+
ask(question: string): Promise<string>;
|
|
10
|
+
readonly env: NodeJS.ProcessEnv;
|
|
11
|
+
}
|
|
12
|
+
export declare function isCi(env: NodeJS.ProcessEnv): boolean;
|
|
13
|
+
export declare function processIo(opts: {
|
|
14
|
+
nonInteractive: boolean;
|
|
15
|
+
noColor: boolean;
|
|
16
|
+
}, env?: NodeJS.ProcessEnv): Io;
|