geopilot 0.0.0-stage → 0.0.1
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 +91 -2
- package/dist/agent/install.d.ts +23 -0
- package/dist/agent/install.js +77 -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 +14 -0
- package/hosts/claude-project/.claude/skills/geo/scripts/geo.sh +13 -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/codex/plugin.json +21 -0
- package/hosts/codex/skills/explain/SKILL.md +38 -0
- package/hosts/codex/skills/fix/SKILL.md +46 -0
- package/hosts/codex/skills/fix/agents/openai.yaml +2 -0
- package/hosts/codex/skills/geo/SKILL.md +95 -0
- package/hosts/codex/skills/geo/references/frameworks.md +20 -0
- package/hosts/codex/skills/geo/references/insight-contract.md +42 -0
- package/hosts/codex/skills/geo/references/safety.md +30 -0
- package/hosts/codex/skills/geo/references/workflow-explain.md +8 -0
- package/hosts/codex/skills/geo/references/workflow-fix.md +20 -0
- package/hosts/codex/skills/geo/references/workflow-init.md +6 -0
- package/hosts/codex/skills/geo/references/workflow-insights.md +13 -0
- package/hosts/codex/skills/geo/references/workflow-plan.md +13 -0
- package/hosts/codex/skills/geo/references/workflow-review.md +8 -0
- package/hosts/codex/skills/geo/references/workflow-scan.md +18 -0
- package/hosts/codex/skills/geo/schemas/insights.schema.json +255 -0
- package/hosts/codex/skills/geo/scripts/geo.ps1 +14 -0
- package/hosts/codex/skills/geo/scripts/geo.sh +13 -0
- package/hosts/codex/skills/init/SKILL.md +13 -0
- package/hosts/codex/skills/init/agents/openai.yaml +2 -0
- package/hosts/codex/skills/insights/SKILL.md +49 -0
- package/hosts/codex/skills/review/SKILL.md +45 -0
- package/hosts/codex/skills/scan/SKILL.md +51 -0
- package/hosts/codex-project/.agents/skills/geo/SKILL.md +95 -0
- package/hosts/codex-project/.agents/skills/geo/references/frameworks.md +20 -0
- package/hosts/codex-project/.agents/skills/geo/references/insight-contract.md +42 -0
- package/hosts/codex-project/.agents/skills/geo/references/safety.md +30 -0
- package/hosts/codex-project/.agents/skills/geo/references/workflow-explain.md +8 -0
- package/hosts/codex-project/.agents/skills/geo/references/workflow-fix.md +20 -0
- package/hosts/codex-project/.agents/skills/geo/references/workflow-init.md +6 -0
- package/hosts/codex-project/.agents/skills/geo/references/workflow-insights.md +13 -0
- package/hosts/codex-project/.agents/skills/geo/references/workflow-plan.md +13 -0
- package/hosts/codex-project/.agents/skills/geo/references/workflow-review.md +8 -0
- package/hosts/codex-project/.agents/skills/geo/references/workflow-scan.md +18 -0
- package/hosts/codex-project/.agents/skills/geo/schemas/insights.schema.json +255 -0
- package/hosts/codex-project/.agents/skills/geo/scripts/geo.ps1 +14 -0
- package/hosts/codex-project/.agents/skills/geo/scripts/geo.sh +13 -0
- package/hosts/codex-project/.agents/skills/geopilot-explain/SKILL.md +8 -0
- package/hosts/codex-project/.agents/skills/geopilot-fix/SKILL.md +10 -0
- package/hosts/codex-project/.agents/skills/geopilot-fix/agents/openai.yaml +2 -0
- package/hosts/codex-project/.agents/skills/geopilot-init/SKILL.md +13 -0
- package/hosts/codex-project/.agents/skills/geopilot-init/agents/openai.yaml +2 -0
- package/hosts/codex-project/.agents/skills/geopilot-insights/SKILL.md +10 -0
- package/hosts/codex-project/.agents/skills/geopilot-review/SKILL.md +10 -0
- package/hosts/codex-project/.agents/skills/geopilot-scan/SKILL.md +10 -0
- package/hosts/codex-project/.codex/agents/geopilot-explainer.toml +34 -0
- package/hosts/codex-project/.codex/agents/geopilot-fixer.toml +40 -0
- package/hosts/codex-project/.codex/agents/geopilot-investigator.toml +43 -0
- package/hosts/codex-project/.codex/agents/geopilot-reviewer.toml +39 -0
- package/hosts/codex-project/.codex/agents/geopilot-scanner.toml +45 -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 +14 -0
- package/hosts/geopilot/skills/geo/scripts/geo.sh +13 -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 +14 -0
- package/hosts/opencode/.opencode/skills/geo/scripts/geo.sh +13 -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 +14 -0
- package/skill/geo/scripts/geo.sh +13 -0
package/dist/cli/io.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { createInterface } from 'node:readline/promises';
|
|
2
|
+
import { colorEnabled, palette } from "../core/tty.js";
|
|
3
|
+
export function isCi(env) {
|
|
4
|
+
return env.CI !== undefined && env.CI !== '' && env.CI !== '0' && env.CI !== 'false';
|
|
5
|
+
}
|
|
6
|
+
export function processIo(opts, env = process.env) {
|
|
7
|
+
const interactive = !opts.nonInteractive && !isCi(env) && Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
8
|
+
const ask = async (question) => {
|
|
9
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
10
|
+
try {
|
|
11
|
+
return (await rl.question(question)).trim();
|
|
12
|
+
}
|
|
13
|
+
finally {
|
|
14
|
+
rl.close();
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
return {
|
|
18
|
+
out: (t) => process.stdout.write(t),
|
|
19
|
+
err: (t) => process.stderr.write(t),
|
|
20
|
+
interactive,
|
|
21
|
+
color: palette(!opts.noColor && colorEnabled(env, Boolean(process.stdout.isTTY)), env),
|
|
22
|
+
errColor: palette(!opts.noColor && colorEnabled(env, Boolean(process.stderr.isTTY)), env),
|
|
23
|
+
confirm: async (q) => interactive && /^y(es)?$/i.test(await ask(`${q} [y/N] `)),
|
|
24
|
+
ask: async (q) => (interactive ? ask(q) : ''),
|
|
25
|
+
env,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=io.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"io.js","sourceRoot":"","sources":["../../src/cli/io.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,OAAO,EAAgB,MAAM,gBAAgB,CAAC;AAerE,MAAM,UAAU,IAAI,CAAC,GAAsB;IACzC,OAAO,GAAG,CAAC,EAAE,KAAK,SAAS,IAAI,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,CAAC,EAAE,KAAK,OAAO,CAAC;AACvF,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAmD,EAAE,MAAyB,OAAO,CAAC,GAAG;IACjH,MAAM,WAAW,GAAG,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/G,MAAM,GAAG,GAAG,KAAK,EAAE,QAAgB,EAAmB,EAAE;QACtD,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7E,IAAI,CAAC;YACH,OAAO,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9C,CAAC;gBAAS,CAAC;YACT,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,CAAC;IACH,CAAC,CAAC;IACF,OAAO;QACL,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACnC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACnC,WAAW;QACX,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;QACtF,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;QACzF,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,WAAW,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC/E,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,GAAG;KACJ,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { type Io } from './io.ts';
|
|
3
|
+
import type { Deps } from './context.ts';
|
|
4
|
+
import { COMMANDS } from './commands-list.ts';
|
|
5
|
+
export { COMMANDS };
|
|
6
|
+
export declare function helpText(): string;
|
|
7
|
+
export declare function commandHelp(name: string): string | null;
|
|
8
|
+
export interface RunDeps {
|
|
9
|
+
readonly io?: Io;
|
|
10
|
+
readonly cwd?: string;
|
|
11
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
12
|
+
readonly fetcher?: Deps['fetcher'];
|
|
13
|
+
readonly now?: () => Date;
|
|
14
|
+
}
|
|
15
|
+
export declare function run(argv: readonly string[], d?: RunDeps): Promise<number>;
|
package/dist/cli/main.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { realpathSync } from 'node:fs';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { EXIT, isGeoError } from "../core/errors.js";
|
|
5
|
+
import { DISCLAIMER, TOOL_VERSION } from "../core/version.js";
|
|
6
|
+
import { processIo } from "./io.js";
|
|
7
|
+
import { scanCommand } from "./commands/scan.js";
|
|
8
|
+
import { explainCommand, rulesCommand } from "./commands/rules.js";
|
|
9
|
+
import { fixCommand } from "./commands/fix.js";
|
|
10
|
+
import { initCommand } from "./commands/init.js";
|
|
11
|
+
import { agentCommand } from "./commands/agent.js";
|
|
12
|
+
import { insightsCommand, reportCommand } from "./commands/insights.js";
|
|
13
|
+
import { COMMANDS } from "./commands-list.js";
|
|
14
|
+
export { COMMANDS };
|
|
15
|
+
export function helpText() {
|
|
16
|
+
const lines = [
|
|
17
|
+
`geopilot ${TOOL_VERSION} — local-first technical readiness auditor`,
|
|
18
|
+
'',
|
|
19
|
+
'Usage: geopilot <command> [options]',
|
|
20
|
+
'',
|
|
21
|
+
'Commands:',
|
|
22
|
+
...COMMANDS.map((c) => ` ${c.name.padEnd(10)} ${c.summary}${c.phase ? ` (${c.phase}; not in this release)` : ''}`),
|
|
23
|
+
'',
|
|
24
|
+
'Global options:',
|
|
25
|
+
' --config <file> --cwd <dir> --format pretty|json|markdown --output <file>',
|
|
26
|
+
' --non-interactive --yes --quiet --verbose --no-color --no-cache --print-config',
|
|
27
|
+
'',
|
|
28
|
+
'Exit codes: 0 ok · 1 gate failed / invalid insights · 2 usage or missing approval · 3 invalid config',
|
|
29
|
+
' 4 incomplete (with --fail-on-incomplete) · 5 fix rolled back · 6 applied but unverified · 70 internal error',
|
|
30
|
+
'',
|
|
31
|
+
`Docs: https://moelzanaty3.github.io/geopilot/docs/`,
|
|
32
|
+
'',
|
|
33
|
+
DISCLAIMER,
|
|
34
|
+
'',
|
|
35
|
+
];
|
|
36
|
+
return lines.join('\n');
|
|
37
|
+
}
|
|
38
|
+
export function commandHelp(name) {
|
|
39
|
+
const c = COMMANDS.find((x) => x.name === name);
|
|
40
|
+
return c ? `geopilot ${c.usage}\n\n${c.summary}.${c.phase ? ` ${c.phase}: not available in this release.` : ''}\n` : null;
|
|
41
|
+
}
|
|
42
|
+
export async function run(argv, d = {}) {
|
|
43
|
+
const env = d.env ?? process.env;
|
|
44
|
+
const io = d.io ?? processIo({ nonInteractive: argv.includes('--non-interactive'), noColor: argv.includes('--no-color') }, env);
|
|
45
|
+
const deps = { io, cwd: d.cwd ?? process.cwd(), env, ...(d.fetcher ? { fetcher: d.fetcher } : {}), ...(d.now ? { now: d.now } : {}) };
|
|
46
|
+
const [command, ...rest] = argv;
|
|
47
|
+
try {
|
|
48
|
+
if (command === undefined || command === '--help' || command === '-h' || command === 'help') {
|
|
49
|
+
const topic = command === 'help' ? rest[0] : undefined;
|
|
50
|
+
io.out(topic ? commandHelp(topic) ?? helpText() : helpText());
|
|
51
|
+
return EXIT.ok;
|
|
52
|
+
}
|
|
53
|
+
if (command === '--version' || command === '-v' || command === 'version') {
|
|
54
|
+
io.out(`${TOOL_VERSION}\n`);
|
|
55
|
+
return EXIT.ok;
|
|
56
|
+
}
|
|
57
|
+
if (rest.includes('--help') || rest.includes('-h')) {
|
|
58
|
+
const h = commandHelp(command);
|
|
59
|
+
if (h) {
|
|
60
|
+
io.out(h);
|
|
61
|
+
return EXIT.ok;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
switch (command) {
|
|
65
|
+
case 'scan':
|
|
66
|
+
return await scanCommand(rest, deps);
|
|
67
|
+
case 'explain':
|
|
68
|
+
return await explainCommand(rest, deps);
|
|
69
|
+
case 'rules':
|
|
70
|
+
return await rulesCommand(rest, deps);
|
|
71
|
+
case 'fix':
|
|
72
|
+
return await fixCommand(rest, deps);
|
|
73
|
+
case 'init':
|
|
74
|
+
return await initCommand(rest, deps);
|
|
75
|
+
case 'agent':
|
|
76
|
+
return await agentCommand(rest, deps);
|
|
77
|
+
case 'insights':
|
|
78
|
+
return await insightsCommand(rest, deps);
|
|
79
|
+
case 'report':
|
|
80
|
+
return await reportCommand(rest, deps);
|
|
81
|
+
case 'review':
|
|
82
|
+
case 'baseline':
|
|
83
|
+
case 'hook':
|
|
84
|
+
io.err(`${command} is a Phase 3 command and is not available in this release.\n`);
|
|
85
|
+
return EXIT.usage;
|
|
86
|
+
default:
|
|
87
|
+
io.err(`unknown command ${command}\n${helpText()}`);
|
|
88
|
+
return EXIT.usage;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
if (isGeoError(e)) {
|
|
93
|
+
io.err(`${io.errColor.red('error')} ${e.message}\n`);
|
|
94
|
+
if (e.hint)
|
|
95
|
+
io.err(` ${io.errColor.dim(e.hint)}\n`);
|
|
96
|
+
return e.exitCode;
|
|
97
|
+
}
|
|
98
|
+
io.err(`${io.errColor.red('internal error')} ${e.stack ?? String(e)}\nPlease report it: https://github.com/moelzanaty3/geopilot/issues\n`);
|
|
99
|
+
return EXIT.internal;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function isMain() {
|
|
103
|
+
try {
|
|
104
|
+
return process.argv[1] !== undefined && realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url));
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (isMain()) {
|
|
111
|
+
run(process.argv.slice(2)).then((code) => {
|
|
112
|
+
process.exitCode = code;
|
|
113
|
+
}, (e) => {
|
|
114
|
+
process.stderr.write(`internal error ${String(e)}\n`);
|
|
115
|
+
process.exitCode = EXIT.internal;
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { type BodyKind, type FetchResult, type NetPolicy } from '../net/fetch.ts';
|
|
2
|
+
import { type Document, type HeadFacts } from '../html/parse.ts';
|
|
3
|
+
import { type ParsedRobots } from '../robots/robots.ts';
|
|
4
|
+
import { type ParsedSitemap } from '../sitemap/sitemap.ts';
|
|
5
|
+
export type Fetcher = (url: string, kind: BodyKind) => Promise<FetchResult>;
|
|
6
|
+
export interface PageObservation {
|
|
7
|
+
readonly url: string;
|
|
8
|
+
readonly result: FetchResult;
|
|
9
|
+
readonly via: 'target' | 'sitemap' | 'link';
|
|
10
|
+
readonly depth: number;
|
|
11
|
+
readonly doc: Document | null;
|
|
12
|
+
readonly facts: HeadFacts | null;
|
|
13
|
+
readonly isHtml: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface UrlEvidence {
|
|
16
|
+
readonly origin: string;
|
|
17
|
+
readonly targets: readonly string[];
|
|
18
|
+
readonly robots: {
|
|
19
|
+
readonly url: string;
|
|
20
|
+
readonly result: FetchResult;
|
|
21
|
+
readonly parsed: ParsedRobots | null;
|
|
22
|
+
};
|
|
23
|
+
readonly sitemaps: readonly {
|
|
24
|
+
readonly url: string;
|
|
25
|
+
readonly result: FetchResult;
|
|
26
|
+
readonly parsed: ParsedSitemap | null;
|
|
27
|
+
readonly via: 'robots' | 'default' | 'index';
|
|
28
|
+
}[];
|
|
29
|
+
readonly sitemapUrls: readonly string[];
|
|
30
|
+
readonly pages: ReadonlyMap<string, PageObservation>;
|
|
31
|
+
/** Normalised target URL → pages whose server HTML links to it. */
|
|
32
|
+
readonly inbound: ReadonlyMap<string, ReadonlySet<string>>;
|
|
33
|
+
readonly extras: ReadonlyMap<string, FetchResult>;
|
|
34
|
+
readonly skippedByRobots: readonly string[];
|
|
35
|
+
readonly ignoreRobots: boolean;
|
|
36
|
+
readonly notes: readonly string[];
|
|
37
|
+
}
|
|
38
|
+
export interface CrawlOptions {
|
|
39
|
+
readonly targets: readonly string[];
|
|
40
|
+
readonly maxPages: number;
|
|
41
|
+
readonly maxDepth: number;
|
|
42
|
+
readonly followExternal: boolean;
|
|
43
|
+
readonly ignoreRobots: boolean;
|
|
44
|
+
readonly include: (path: string) => boolean;
|
|
45
|
+
readonly extraPaths: readonly string[];
|
|
46
|
+
readonly fetcher: Fetcher;
|
|
47
|
+
}
|
|
48
|
+
export declare const GEO_UA_TOKEN = "geopilot";
|
|
49
|
+
export declare function normaliseUrl(input: string, base?: string): string | null;
|
|
50
|
+
export declare function defaultFetcher(policy: NetPolicy): Fetcher;
|
|
51
|
+
export declare function crawl(opts: CrawlOptions): Promise<UrlEvidence>;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { guardedFetch, HostScheduler } from "../net/fetch.js";
|
|
2
|
+
import { isLoopbackUrl } from "../net/address.js";
|
|
3
|
+
import { headFacts, parseHtml } from "../html/parse.js";
|
|
4
|
+
import { evaluate, parseRobots } from "../robots/robots.js";
|
|
5
|
+
import { parseSitemap } from "../sitemap/sitemap.js";
|
|
6
|
+
export const GEO_UA_TOKEN = 'geopilot';
|
|
7
|
+
export function normaliseUrl(input, base) {
|
|
8
|
+
try {
|
|
9
|
+
const u = base ? new URL(input, base) : new URL(input);
|
|
10
|
+
if (u.protocol !== 'http:' && u.protocol !== 'https:')
|
|
11
|
+
return null;
|
|
12
|
+
u.hash = '';
|
|
13
|
+
return u.href;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function defaultFetcher(policy) {
|
|
20
|
+
const scheduler = new HostScheduler();
|
|
21
|
+
return (url, kind) => {
|
|
22
|
+
let host = url;
|
|
23
|
+
let local = false;
|
|
24
|
+
try {
|
|
25
|
+
const u = new URL(url);
|
|
26
|
+
host = u.host;
|
|
27
|
+
local = isLoopbackUrl(u);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// guardedFetch reports the malformed URL itself
|
|
31
|
+
}
|
|
32
|
+
return scheduler.run(host, local, () => guardedFetch(url, kind, policy));
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function allowedHost(url, origin, followExternal) {
|
|
36
|
+
if (url.origin === origin.origin)
|
|
37
|
+
return true;
|
|
38
|
+
if (!followExternal)
|
|
39
|
+
return false;
|
|
40
|
+
const base = origin.hostname.replace(/^www\./, '');
|
|
41
|
+
return url.hostname === base || url.hostname.endsWith(`.${base}`);
|
|
42
|
+
}
|
|
43
|
+
function isHtmlResponse(r) {
|
|
44
|
+
const ct = (r.headers['content-type'] ?? '').toLowerCase();
|
|
45
|
+
return ct === '' ? /^\s*(<!doctype html|<html)/i.test(r.body) : ct.includes('html');
|
|
46
|
+
}
|
|
47
|
+
export async function crawl(opts) {
|
|
48
|
+
const first = new URL(opts.targets[0]);
|
|
49
|
+
const origin = new URL(first.origin);
|
|
50
|
+
const notes = [];
|
|
51
|
+
const f = opts.fetcher;
|
|
52
|
+
const robotsUrl = new URL('/robots.txt', origin).href;
|
|
53
|
+
const robotsResult = await f(robotsUrl, 'robots');
|
|
54
|
+
const robotsParsed = robotsResult.status !== null && robotsResult.status >= 200 && robotsResult.status < 300 ? parseRobots(robotsResult.body) : null;
|
|
55
|
+
if (robotsParsed) {
|
|
56
|
+
const delay = robotsParsed.groups.find((g) => g.agents.includes(GEO_UA_TOKEN) || g.agents.includes('*'))?.crawlDelay;
|
|
57
|
+
if (delay)
|
|
58
|
+
notes.push(`robots.txt asks for a crawl-delay of ${delay}s; GEO honours up to 2s`);
|
|
59
|
+
}
|
|
60
|
+
const robotsServerError = robotsResult.status !== null && robotsResult.status >= 500;
|
|
61
|
+
const robotsUnreachable = robotsResult.error !== null;
|
|
62
|
+
const mayFetch = (url) => {
|
|
63
|
+
if (opts.ignoreRobots)
|
|
64
|
+
return true;
|
|
65
|
+
// RFC 9309 2.3.1.4: an unreachable or 5xx robots.txt means assume complete disallow.
|
|
66
|
+
if (robotsServerError || robotsUnreachable)
|
|
67
|
+
return false;
|
|
68
|
+
if (!robotsParsed)
|
|
69
|
+
return true;
|
|
70
|
+
const u = new URL(url);
|
|
71
|
+
return evaluate(robotsParsed, GEO_UA_TOKEN, `${u.pathname}${u.search}`).allowed;
|
|
72
|
+
};
|
|
73
|
+
const sitemaps = [];
|
|
74
|
+
const sitemapUrls = [];
|
|
75
|
+
const sitemapQueue = [];
|
|
76
|
+
for (const s of robotsParsed?.sitemaps ?? []) {
|
|
77
|
+
const n = normaliseUrl(s.url);
|
|
78
|
+
if (n && allowedHost(new URL(n), origin, opts.followExternal))
|
|
79
|
+
sitemapQueue.push({ url: n, via: 'robots' });
|
|
80
|
+
}
|
|
81
|
+
if (sitemapQueue.length === 0)
|
|
82
|
+
sitemapQueue.push({ url: new URL('/sitemap.xml', origin).href, via: 'default' });
|
|
83
|
+
const seenSitemaps = new Set();
|
|
84
|
+
while (sitemapQueue.length > 0 && seenSitemaps.size < 6) {
|
|
85
|
+
const next = sitemapQueue.shift();
|
|
86
|
+
if (seenSitemaps.has(next.url))
|
|
87
|
+
continue;
|
|
88
|
+
seenSitemaps.add(next.url);
|
|
89
|
+
if (!mayFetch(next.url))
|
|
90
|
+
continue;
|
|
91
|
+
const result = await f(next.url, 'sitemap');
|
|
92
|
+
const ok = result.status !== null && result.status >= 200 && result.status < 300;
|
|
93
|
+
const parsed = ok ? parseSitemap(result.body) : null;
|
|
94
|
+
sitemaps.push({ url: next.url, result, parsed, via: next.via });
|
|
95
|
+
if (parsed?.kind === 'sitemapindex') {
|
|
96
|
+
for (const loc of parsed.locs.slice(0, 5))
|
|
97
|
+
sitemapQueue.push({ url: loc, via: 'index' });
|
|
98
|
+
}
|
|
99
|
+
else if (parsed?.kind === 'urlset') {
|
|
100
|
+
for (const loc of parsed.locs)
|
|
101
|
+
sitemapUrls.push(loc);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const pages = new Map();
|
|
105
|
+
const inbound = new Map();
|
|
106
|
+
const skippedByRobots = [];
|
|
107
|
+
const queue = [];
|
|
108
|
+
const queued = new Set();
|
|
109
|
+
const enqueue = (url, via, depth) => {
|
|
110
|
+
const n = normaliseUrl(url);
|
|
111
|
+
if (!n || queued.has(n))
|
|
112
|
+
return;
|
|
113
|
+
const u = new URL(n);
|
|
114
|
+
if (!allowedHost(u, origin, opts.followExternal) || !opts.include(u.pathname))
|
|
115
|
+
return;
|
|
116
|
+
queued.add(n);
|
|
117
|
+
queue.push({ url: n, via, depth });
|
|
118
|
+
};
|
|
119
|
+
for (const t of opts.targets)
|
|
120
|
+
enqueue(t, 'target', 0);
|
|
121
|
+
for (const s of sitemapUrls)
|
|
122
|
+
enqueue(s, 'sitemap', 1);
|
|
123
|
+
while (queue.length > 0 && pages.size < opts.maxPages) {
|
|
124
|
+
const batch = queue.splice(0, Math.min(4, opts.maxPages - pages.size));
|
|
125
|
+
await Promise.all(batch.map(async (item) => {
|
|
126
|
+
if (!mayFetch(item.url)) {
|
|
127
|
+
skippedByRobots.push(item.url);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const result = await f(item.url, 'html');
|
|
131
|
+
const html = result.error === null && isHtmlResponse(result);
|
|
132
|
+
const doc = html ? parseHtml(result.body) : null;
|
|
133
|
+
const facts = doc ? headFacts(doc) : null;
|
|
134
|
+
pages.set(item.url, { url: item.url, result, via: item.via, depth: item.depth, doc, facts, isHtml: html });
|
|
135
|
+
if (!facts)
|
|
136
|
+
return;
|
|
137
|
+
for (const href of facts.links) {
|
|
138
|
+
const target = normaliseUrl(href, result.finalUrl);
|
|
139
|
+
if (!target)
|
|
140
|
+
continue;
|
|
141
|
+
if (!inbound.has(target))
|
|
142
|
+
inbound.set(target, new Set());
|
|
143
|
+
inbound.get(target).add(item.url);
|
|
144
|
+
if (item.depth < opts.maxDepth)
|
|
145
|
+
enqueue(target, 'link', item.depth + 1);
|
|
146
|
+
}
|
|
147
|
+
}));
|
|
148
|
+
}
|
|
149
|
+
if (queue.length > 0)
|
|
150
|
+
notes.push(`page budget of ${opts.maxPages} reached; ${queue.length} discovered URLs were not fetched`);
|
|
151
|
+
if (skippedByRobots.length > 0)
|
|
152
|
+
notes.push(`${skippedByRobots.length} URLs were not fetched because robots.txt disallows ${GEO_UA_TOKEN}`);
|
|
153
|
+
const extras = new Map();
|
|
154
|
+
for (const path of opts.extraPaths) {
|
|
155
|
+
const url = new URL(path, origin).href;
|
|
156
|
+
if (!mayFetch(url))
|
|
157
|
+
continue;
|
|
158
|
+
extras.set(url, await f(url, path.endsWith('.json') || path.includes('apple-app-site') ? 'json' : 'robots'));
|
|
159
|
+
}
|
|
160
|
+
const canonicalTargets = new Set();
|
|
161
|
+
for (const page of pages.values()) {
|
|
162
|
+
for (const c of page.facts?.canonical ?? []) {
|
|
163
|
+
const n = normaliseUrl(c, page.result.finalUrl);
|
|
164
|
+
if (n && !pages.has(n) && allowedHost(new URL(n), origin, opts.followExternal))
|
|
165
|
+
canonicalTargets.add(n);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
for (const target of [...canonicalTargets].slice(0, 25)) {
|
|
169
|
+
if (!mayFetch(target))
|
|
170
|
+
continue;
|
|
171
|
+
extras.set(target, await f(target, 'html'));
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
origin: origin.origin,
|
|
175
|
+
targets: opts.targets,
|
|
176
|
+
robots: { url: robotsUrl, result: robotsResult, parsed: robotsParsed },
|
|
177
|
+
sitemaps,
|
|
178
|
+
sitemapUrls,
|
|
179
|
+
pages,
|
|
180
|
+
inbound,
|
|
181
|
+
extras,
|
|
182
|
+
skippedByRobots,
|
|
183
|
+
ignoreRobots: opts.ignoreRobots,
|
|
184
|
+
notes,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=crawl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crawl.js","sourceRoot":"","sources":["../../src/collect/crawl.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { RuleId, Severity } from '../types.ts';
|
|
2
|
+
export type RenderMode = 'auto' | 'always' | 'never';
|
|
3
|
+
export type CrawlerPolicy = 'allow' | 'block' | 'undecided';
|
|
4
|
+
export type FrameworkSetting = 'auto' | 'nextjs-app' | 'static' | 'generic';
|
|
5
|
+
export interface Suppression {
|
|
6
|
+
readonly rule: RuleId;
|
|
7
|
+
readonly routes: readonly string[];
|
|
8
|
+
readonly reason: string;
|
|
9
|
+
readonly expires: string | null;
|
|
10
|
+
}
|
|
11
|
+
export interface GeoConfig {
|
|
12
|
+
readonly version: 1;
|
|
13
|
+
readonly framework: FrameworkSetting;
|
|
14
|
+
readonly profile: 'web' | 'app';
|
|
15
|
+
readonly site: {
|
|
16
|
+
readonly origin: string | null;
|
|
17
|
+
readonly language: string | null;
|
|
18
|
+
};
|
|
19
|
+
readonly routes: {
|
|
20
|
+
readonly include: readonly string[];
|
|
21
|
+
readonly exclude: readonly string[];
|
|
22
|
+
};
|
|
23
|
+
readonly crawl: {
|
|
24
|
+
readonly maxPages: number | null;
|
|
25
|
+
readonly maxDepth: number;
|
|
26
|
+
readonly render: RenderMode;
|
|
27
|
+
readonly requestTimeoutMs: number;
|
|
28
|
+
};
|
|
29
|
+
readonly policy: {
|
|
30
|
+
readonly aiSearchCrawlers: CrawlerPolicy;
|
|
31
|
+
readonly aiTrainingCrawlers: CrawlerPolicy;
|
|
32
|
+
readonly userTriggeredFetchers: CrawlerPolicy;
|
|
33
|
+
};
|
|
34
|
+
readonly appLinks: {
|
|
35
|
+
readonly ios: {
|
|
36
|
+
readonly appIds: readonly string[];
|
|
37
|
+
} | null;
|
|
38
|
+
readonly android: {
|
|
39
|
+
readonly packageName: string;
|
|
40
|
+
readonly sha256CertFingerprints: readonly string[];
|
|
41
|
+
} | null;
|
|
42
|
+
};
|
|
43
|
+
readonly rules: Readonly<Partial<Record<RuleId, 'off' | {
|
|
44
|
+
readonly severity: Severity;
|
|
45
|
+
}>>>;
|
|
46
|
+
readonly suppress: readonly Suppression[];
|
|
47
|
+
readonly fix: {
|
|
48
|
+
readonly verifyCommands: readonly (readonly string[])[];
|
|
49
|
+
readonly runtimeTimeoutSeconds: number;
|
|
50
|
+
readonly serve: {
|
|
51
|
+
readonly command: readonly string[] | null;
|
|
52
|
+
readonly url: string | null;
|
|
53
|
+
readonly readyTimeoutSeconds: number;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
readonly thresholds: {
|
|
57
|
+
readonly failOn: Severity | null;
|
|
58
|
+
readonly minReadiness: number | null;
|
|
59
|
+
readonly minCoverage: number;
|
|
60
|
+
};
|
|
61
|
+
readonly hook: {
|
|
62
|
+
readonly failOn: Severity | null;
|
|
63
|
+
readonly timeoutSeconds: number;
|
|
64
|
+
};
|
|
65
|
+
readonly experimental: boolean;
|
|
66
|
+
}
|
|
67
|
+
export declare const DEFAULT_CONFIG: GeoConfig;
|
|
68
|
+
export declare const CONFIG_FILE = "geo.config.json";
|
|
69
|
+
/**
|
|
70
|
+
* Validate a parsed geo.config.json and merge it over `base`. Unknown keys are
|
|
71
|
+
* errors (spec 6): a typo in a policy key must not silently fall back to a
|
|
72
|
+
* default the owner did not choose.
|
|
73
|
+
*/
|
|
74
|
+
export declare function validateConfig(raw: unknown, base?: GeoConfig, source?: string): GeoConfig;
|
|
75
|
+
export declare function readConfigFile(path: string, base: GeoConfig): GeoConfig;
|
|
76
|
+
/** Overrides applied after files: documented GEO_* variables. */
|
|
77
|
+
export declare function envOverrides(env: NodeJS.ProcessEnv, c: GeoConfig): GeoConfig;
|
|
78
|
+
export interface LoadedConfig {
|
|
79
|
+
readonly config: GeoConfig;
|
|
80
|
+
readonly files: readonly string[];
|
|
81
|
+
readonly hash: string;
|
|
82
|
+
}
|
|
83
|
+
/** Root config first, then the workspace config in `cwd`, then environment. */
|
|
84
|
+
export declare function loadConfig(cwd: string, repoRoot: string | null, explicit: string | null, env: NodeJS.ProcessEnv): LoadedConfig;
|
|
85
|
+
/** The effective configuration for --print-config. It holds no secrets by construction. */
|
|
86
|
+
export declare function printableConfig(c: GeoConfig): string;
|