cubest 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 +201 -0
- package/NOTICE +27 -0
- package/README.ar.md +110 -0
- package/README.bn.md +111 -0
- package/README.es.md +110 -0
- package/README.hi.md +110 -0
- package/README.ja.md +113 -0
- package/README.md +469 -0
- package/README.pa.md +114 -0
- package/README.pt.md +113 -0
- package/README.ru.md +1174 -0
- package/README.zh-CN.md +233 -0
- package/bin/cubest.js +28 -0
- package/cubest.py +1862 -0
- package/package.json +28 -0
- package/profiles/agents_inventory.yaml +15 -0
- package/profiles/api_routes.yaml +20 -0
- package/profiles/call_graph.yaml +19 -0
- package/profiles/code_atlas.yaml +33 -0
- package/profiles/code_stats.yaml +15 -0
- package/profiles/csv_analytics.yaml +31 -0
- package/profiles/disk_usage.yaml +29 -0
- package/profiles/doc_structure.yaml +16 -0
- package/profiles/file_tree.yaml +27 -0
- package/profiles/frontend_geoip.yaml +49 -0
- package/profiles/git_log_activity.yaml +29 -0
- package/profiles/imports.yaml +16 -0
- package/profiles/jsonl_events.yaml +19 -0
- package/profiles/k8s_resources.yaml +25 -0
- package/profiles/loc_counter.yaml +51 -0
- package/profiles/mr_impact.yaml +19 -0
- package/profiles/nginx_access.yaml +33 -0
- package/profiles/nginx_cdn_covers.yaml +32 -0
- package/profiles/openapi_endpoints.yaml +19 -0
- package/profiles/react_components.yaml +15 -0
- package/profiles/sdd_checklist.yaml +17 -0
- package/profiles/sdd_specs.yaml +19 -0
- package/profiles/seo_audit.yaml +31 -0
- package/profiles/seo_semantic_tree.yaml +17 -0
- package/profiles/sitemap_map.yaml +20 -0
- package/profiles/skills_inventory.yaml +17 -0
- package/profiles/spec_status.yaml +18 -0
- package/profiles/sql_functions.yaml +31 -0
- package/profiles/tech_debt.yaml +16 -0
- package/profiles/xml_tags.yaml +21 -0
- package/profiles/yaml_keys.yaml +19 -0
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cubest",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Single-pass OLAP aggregator over any text stream (code, logs, CSV, JSONL, XML, SDD artefacts) → 12 output formats including ECharts HTML. Token-cheap alternative to grep+cat chains for LLM agents. npm wrapper — installs Python cubest via pipx or delegates to python3.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"olap", "aggregator", "cli", "log-analysis", "observability", "sre",
|
|
7
|
+
"devops", "echarts", "graphviz", "mermaid", "plantuml", "code-analysis",
|
|
8
|
+
"loc-counter", "seo-audit", "sitemap", "llm", "claude-code", "ai-agents",
|
|
9
|
+
"token-optimization", "regex", "nginx", "percentile"
|
|
10
|
+
],
|
|
11
|
+
"author": "Sergey Baryshev",
|
|
12
|
+
"license": "Apache-2.0",
|
|
13
|
+
"homepage": "https://github.com/BaryshevS/cubest#readme",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/BaryshevS/cubest.git"
|
|
17
|
+
},
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/BaryshevS/cubest/issues"
|
|
20
|
+
},
|
|
21
|
+
"bin": {
|
|
22
|
+
"cubest": "bin/cubest.js"
|
|
23
|
+
},
|
|
24
|
+
"files": ["bin/", "cubest.py", "profiles/", "README.md", "LICENSE", "NOTICE"],
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=14"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
name: agents_inventory
|
|
2
|
+
description: "Claude subagent catalog: model × name via frontmatter of agents/*.md"
|
|
3
|
+
scan:
|
|
4
|
+
include: ["agents/**/*.md", "*/agents/*.md", "**/subagents/*.md"]
|
|
5
|
+
dimensions: [model, name]
|
|
6
|
+
measures:
|
|
7
|
+
- name: count
|
|
8
|
+
type: count
|
|
9
|
+
extract:
|
|
10
|
+
- type: preset
|
|
11
|
+
preset: md_frontmatter
|
|
12
|
+
output:
|
|
13
|
+
format: flat
|
|
14
|
+
top_n: 60
|
|
15
|
+
max_lines: 120
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: api_routes
|
|
2
|
+
description: "FastAPI/Flask/Django endpoints by HTTP method and file"
|
|
3
|
+
scan:
|
|
4
|
+
include: ["*.py"]
|
|
5
|
+
exclude: ["*test*", "venv/*", ".venv/*", "__pycache__/*"]
|
|
6
|
+
dimensions: [method, file]
|
|
7
|
+
measures:
|
|
8
|
+
- name: count
|
|
9
|
+
type: count
|
|
10
|
+
extract:
|
|
11
|
+
- type: regex
|
|
12
|
+
pattern: |
|
|
13
|
+
@(?:app|router|blueprint)\.\s*
|
|
14
|
+
(?P<method>get|post|put|delete|patch|options|head)
|
|
15
|
+
\s*\(\s*['"](?P<route>[^'"]+)['"]
|
|
16
|
+
multiline: true
|
|
17
|
+
ignorecase: true
|
|
18
|
+
output:
|
|
19
|
+
format: tree
|
|
20
|
+
top_n: 20
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: call_graph
|
|
2
|
+
description: "Approximate call graph: caller → callee (Python-like indent scope). Emit as GraphViz DOT. For exact AST-level graph use tree-sitter tools (Graphify)."
|
|
3
|
+
scan:
|
|
4
|
+
include: ["*.py"]
|
|
5
|
+
exclude: [".git/", "node_modules/", "venv/", ".venv/", "__pycache__/",
|
|
6
|
+
"*_test.py", "tests/", "test_*.py"]
|
|
7
|
+
dimensions: [caller, callee]
|
|
8
|
+
measures:
|
|
9
|
+
- name: calls
|
|
10
|
+
type: count
|
|
11
|
+
extract:
|
|
12
|
+
- type: preset
|
|
13
|
+
preset: calls
|
|
14
|
+
filters:
|
|
15
|
+
- "caller != callee" # drop trivial self-loops
|
|
16
|
+
output:
|
|
17
|
+
format: dot
|
|
18
|
+
top_n: 200
|
|
19
|
+
min_count: 1
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: code_atlas
|
|
2
|
+
description: "Multi-language code map: language × file × function (top 10 languages by extension). Python funcs get nesting (parent, depth)."
|
|
3
|
+
scan:
|
|
4
|
+
include:
|
|
5
|
+
- "*.py"
|
|
6
|
+
- "*.js"
|
|
7
|
+
- "*.ts"
|
|
8
|
+
- "*.jsx"
|
|
9
|
+
- "*.tsx"
|
|
10
|
+
- "*.go"
|
|
11
|
+
- "*.rs"
|
|
12
|
+
- "*.java"
|
|
13
|
+
- "*.rb"
|
|
14
|
+
- "*.php"
|
|
15
|
+
- "*.kt"
|
|
16
|
+
- "*.swift"
|
|
17
|
+
- "*.c"
|
|
18
|
+
- "*.cpp"
|
|
19
|
+
- "*.sh"
|
|
20
|
+
exclude: [".git/", "node_modules/", "vendor/", "dist/", "build/",
|
|
21
|
+
"target/", "__pycache__/", "*.test.*", "*_test.go", "*.spec.*"]
|
|
22
|
+
dimensions: [lang, file, parent, name]
|
|
23
|
+
measures:
|
|
24
|
+
- name: symbols
|
|
25
|
+
type: count
|
|
26
|
+
extract:
|
|
27
|
+
- type: preset
|
|
28
|
+
preset: funcs
|
|
29
|
+
output:
|
|
30
|
+
format: tree
|
|
31
|
+
top_n: 20
|
|
32
|
+
min_count: 1
|
|
33
|
+
max_lines: 150
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
name: code_stats
|
|
2
|
+
description: "Classes and functions per file with average lines"
|
|
3
|
+
scan:
|
|
4
|
+
include: ["*.py", "*.js", "*.ts", "*.go", "*.rs"]
|
|
5
|
+
exclude: ["node_modules/*", "vendor/*", "*_test.go"]
|
|
6
|
+
dimensions: [kind, file]
|
|
7
|
+
measures:
|
|
8
|
+
- name: count
|
|
9
|
+
type: count
|
|
10
|
+
extract:
|
|
11
|
+
- type: preset
|
|
12
|
+
preset: funcs
|
|
13
|
+
output:
|
|
14
|
+
format: tree
|
|
15
|
+
min_count: 1
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: csv_analytics
|
|
2
|
+
description: "Ad/analytics tabular exports (GA4/AdWords/Yandex Metrica/Facebook Ads CSV or TSV). Native CSV parser with header row auto-detect. Column names are lowercased + non-alnum → _."
|
|
3
|
+
scan:
|
|
4
|
+
include: ["*.csv", "*.tsv", "*.csv.gz", "*.tsv.gz"]
|
|
5
|
+
# `csv` preset forces batch mode (needs whole file for header parsing).
|
|
6
|
+
dimensions: [campaign, device]
|
|
7
|
+
measures:
|
|
8
|
+
- name: rows
|
|
9
|
+
type: count
|
|
10
|
+
- name: impressions
|
|
11
|
+
type: sum
|
|
12
|
+
field: impressions
|
|
13
|
+
- name: clicks
|
|
14
|
+
type: sum
|
|
15
|
+
field: clicks
|
|
16
|
+
- name: cost
|
|
17
|
+
type: sum
|
|
18
|
+
field: cost
|
|
19
|
+
- name: cost_p95
|
|
20
|
+
type: p95
|
|
21
|
+
field: cost
|
|
22
|
+
extract:
|
|
23
|
+
- type: preset
|
|
24
|
+
preset: csv # use `tsv` for tab-separated; add `sep: ";"` for European CSV
|
|
25
|
+
# header: true # default; can also pass explicit list: [campaign, device, ...]
|
|
26
|
+
# skip: 1 # extra rows to drop before header (e.g. GA4 report header)
|
|
27
|
+
output:
|
|
28
|
+
format: flat
|
|
29
|
+
top_n: 30
|
|
30
|
+
min_count: 1
|
|
31
|
+
max_lines: 80
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: disk_usage
|
|
2
|
+
description: "Disk usage aggregation up to depth 2. Use dimensions=[path_1..path_N] to change the level. Optional content_match filter includes only files with matching contents."
|
|
3
|
+
scan:
|
|
4
|
+
include: ["*"]
|
|
5
|
+
exclude: [".git/", "node_modules/", "__pycache__/", ".venv/", "venv/",
|
|
6
|
+
"dist/", "build/", "*.lock"]
|
|
7
|
+
# Uncomment to include only files whose content matches (regex):
|
|
8
|
+
# content_match: ["TODO", "@deprecated"]
|
|
9
|
+
# content_not: ["generated"]
|
|
10
|
+
# content_scan_bytes: 65536 # scan only first 64KiB per file (fast pre-check)
|
|
11
|
+
dimensions: [path_1, path_2]
|
|
12
|
+
measures:
|
|
13
|
+
- name: files
|
|
14
|
+
type: count
|
|
15
|
+
- name: bytes
|
|
16
|
+
type: sum
|
|
17
|
+
field: size
|
|
18
|
+
- name: max_file
|
|
19
|
+
type: max
|
|
20
|
+
field: size
|
|
21
|
+
extract:
|
|
22
|
+
- type: preset
|
|
23
|
+
preset: paths
|
|
24
|
+
output:
|
|
25
|
+
format: flat
|
|
26
|
+
top_n: 20
|
|
27
|
+
min_count: 1
|
|
28
|
+
human_bytes: true
|
|
29
|
+
max_lines: 60
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
name: doc_structure
|
|
2
|
+
description: "Markdown headers grouped by file and level"
|
|
3
|
+
scan:
|
|
4
|
+
include: ["*.md", "*.mdx"]
|
|
5
|
+
exclude: ["node_modules/*"]
|
|
6
|
+
dimensions: [file, level]
|
|
7
|
+
measures:
|
|
8
|
+
- name: count
|
|
9
|
+
type: count
|
|
10
|
+
extract:
|
|
11
|
+
- type: preset
|
|
12
|
+
preset: headers
|
|
13
|
+
filters:
|
|
14
|
+
- "level <= 3"
|
|
15
|
+
output:
|
|
16
|
+
format: tree
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: file_tree
|
|
2
|
+
description: "File tree by top-level directory and extension (no content read)"
|
|
3
|
+
scan:
|
|
4
|
+
include: ["*"]
|
|
5
|
+
exclude:
|
|
6
|
+
- ".git/"
|
|
7
|
+
- "node_modules/"
|
|
8
|
+
- "__pycache__/"
|
|
9
|
+
- ".venv/"
|
|
10
|
+
- "venv/"
|
|
11
|
+
- "dist/"
|
|
12
|
+
- "build/"
|
|
13
|
+
- "*.lock"
|
|
14
|
+
- "*.pyc"
|
|
15
|
+
dimensions: [top, ext]
|
|
16
|
+
measures:
|
|
17
|
+
- name: count
|
|
18
|
+
type: count
|
|
19
|
+
- name: bytes
|
|
20
|
+
type: sum
|
|
21
|
+
field: size
|
|
22
|
+
extract:
|
|
23
|
+
- type: preset
|
|
24
|
+
preset: paths
|
|
25
|
+
output:
|
|
26
|
+
format: tree
|
|
27
|
+
min_count: 1
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: frontend_geoip
|
|
2
|
+
description: "Frontend/CDN access log analysis with GeoIP: filter by country + UA + endpoint + status 200; group by file extension; show hits, p90(duration), avg(size). Expects log rows enriched with GeoIP fields (see README `tools/geoip_enrich.sh`). Usage example — mobile Chrome from US/CA for /pub/covers/*: `python cubest.py --profile frontend_geoip enriched.log.gz`"
|
|
3
|
+
scan:
|
|
4
|
+
include: ["access*.log*", "*.enriched.log*", "cdn*.log*"]
|
|
5
|
+
stream: true
|
|
6
|
+
dimensions: [ext]
|
|
7
|
+
measures:
|
|
8
|
+
- name: hits
|
|
9
|
+
type: count
|
|
10
|
+
- name: p50_ms
|
|
11
|
+
type: p50
|
|
12
|
+
field: duration
|
|
13
|
+
- name: p90_ms
|
|
14
|
+
type: p90
|
|
15
|
+
field: duration
|
|
16
|
+
- name: p99_ms
|
|
17
|
+
type: p99
|
|
18
|
+
field: duration
|
|
19
|
+
- name: avg_size
|
|
20
|
+
type: avg
|
|
21
|
+
field: bytes
|
|
22
|
+
- name: bytes_total
|
|
23
|
+
type: sum
|
|
24
|
+
field: bytes
|
|
25
|
+
extract:
|
|
26
|
+
# Expected enriched combined format (tab-separated tail with country code):
|
|
27
|
+
# IP - - [datetime] "METHOD /path HTTP/x.y" status bytes "referer" "UA" duration COUNTRY REGION
|
|
28
|
+
# Adjust the regex to match your ingest schema. Country + region come from
|
|
29
|
+
# GeoIP enrichment step (see `tools/geoip_enrich.sh`).
|
|
30
|
+
- type: regex
|
|
31
|
+
multiline: false
|
|
32
|
+
pattern: >-
|
|
33
|
+
(?P<ip>\d+\.\d+\.\d+\.\d+)\s+\S+\s+\S+\s+\[(?P<datetime>[^\]]+)\]\s+"(?P<method>GET|POST|PUT|DELETE|HEAD|OPTIONS|PATCH)\s+(?P<path>/[^\s?"]+)(?:\?[^\s"]*)?\s+HTTP/[\d.]+"\s+(?P<status>\d{3})\s+(?P<bytes>\d+)\s+"[^"]*"\s+"(?P<ua>[^"]*)"\s+(?P<duration>[0-9.]+)\s+(?P<country>[A-Z]{2})(?:\s+(?P<region>[A-Z0-9\-]+))?
|
|
34
|
+
# Second rule extracts extension from path (works because iteration
|
|
35
|
+
# merges named groups into the same record when applied to same line).
|
|
36
|
+
- type: regex
|
|
37
|
+
multiline: false
|
|
38
|
+
pattern: '/pub/covers/[^\s?"]+\.(?P<ext>webp|jpg|png|avif|gif)'
|
|
39
|
+
ignorecase: true
|
|
40
|
+
filters:
|
|
41
|
+
- "status == 200"
|
|
42
|
+
- "country == 'US' or country == 'CA'"
|
|
43
|
+
- "'Mobile' in ua and 'Chrome' in ua"
|
|
44
|
+
- "ext in ('webp', 'jpg', 'png', 'avif', 'gif')"
|
|
45
|
+
output:
|
|
46
|
+
format: echarts
|
|
47
|
+
chart_type: bar
|
|
48
|
+
top_n: 20
|
|
49
|
+
title: "Mobile Chrome (US/CA) /pub/covers/* — 200 by ext"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: git_log_activity
|
|
2
|
+
description: "Author × month activity from `git log --numstat --format=...` output piped as a single file. Requires a specific pretty format."
|
|
3
|
+
scan:
|
|
4
|
+
include: ["*.log", "*.txt"]
|
|
5
|
+
stream: true
|
|
6
|
+
dimensions: [author, month]
|
|
7
|
+
measures:
|
|
8
|
+
- name: commits
|
|
9
|
+
type: count
|
|
10
|
+
- name: added
|
|
11
|
+
type: sum
|
|
12
|
+
field: added
|
|
13
|
+
- name: removed
|
|
14
|
+
type: sum
|
|
15
|
+
field: removed
|
|
16
|
+
extract:
|
|
17
|
+
# Feed with:
|
|
18
|
+
# git log --numstat --format='COMMIT|%an|%ai' --since=6.months > /tmp/gitlog.txt
|
|
19
|
+
# then parse both a COMMIT header line and numstat lines.
|
|
20
|
+
- type: regex
|
|
21
|
+
multiline: false
|
|
22
|
+
pattern: '^COMMIT\|(?P<author>[^|]+)\|(?P<month>\d{4}-\d{2})'
|
|
23
|
+
- type: regex
|
|
24
|
+
multiline: false
|
|
25
|
+
pattern: '^(?P<added>\d+)\s+(?P<removed>\d+)\s+\S+'
|
|
26
|
+
output:
|
|
27
|
+
format: md_table
|
|
28
|
+
top_n: 40
|
|
29
|
+
max_lines: 60
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
name: imports
|
|
2
|
+
description: "Python imports grouped by module"
|
|
3
|
+
scan:
|
|
4
|
+
include: ["*.py"]
|
|
5
|
+
exclude: ["*test*", "venv/*"]
|
|
6
|
+
dimensions: [module, file]
|
|
7
|
+
measures:
|
|
8
|
+
- name: count
|
|
9
|
+
type: count
|
|
10
|
+
extract:
|
|
11
|
+
- type: regex
|
|
12
|
+
pattern: '^(?:from|import)\s+(?P<module>[a-zA-Z_][a-zA-Z0-9_.]*)'
|
|
13
|
+
- type: regex
|
|
14
|
+
pattern: '^from\s+(?P<module>[a-zA-Z_][a-zA-Z0-9_.]*)\s+import'
|
|
15
|
+
output:
|
|
16
|
+
format: compact
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: jsonl_events
|
|
2
|
+
description: "JSON-lines event stream (app events, ClickHouse SELECT ... FORMAT JSONEachRow, Kafka dumps): event × source with counts"
|
|
3
|
+
scan:
|
|
4
|
+
include: ["*.jsonl", "*.jsonl.gz", "*.ndjson", "*.ndjson.gz"]
|
|
5
|
+
stream: true
|
|
6
|
+
dimensions: [event, source]
|
|
7
|
+
measures:
|
|
8
|
+
- name: rows
|
|
9
|
+
type: count
|
|
10
|
+
extract:
|
|
11
|
+
- type: regex
|
|
12
|
+
multiline: false
|
|
13
|
+
pattern: >-
|
|
14
|
+
"event"\s*:\s*"(?P<event>[^"]+)"[^\n]*?"source"\s*:\s*"(?P<source>[^"]+)"
|
|
15
|
+
output:
|
|
16
|
+
format: flat
|
|
17
|
+
top_n: 30
|
|
18
|
+
min_count: 1
|
|
19
|
+
max_lines: 80
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: k8s_resources
|
|
2
|
+
description: "Kubernetes manifests inventory: kind × namespace × name across a helm chart / kustomize / raw yaml tree."
|
|
3
|
+
scan:
|
|
4
|
+
include: ["*.yaml", "*.yml"]
|
|
5
|
+
exclude: [".git/", "node_modules/"]
|
|
6
|
+
content_match: ['^apiVersion:\s']
|
|
7
|
+
stream: true
|
|
8
|
+
dimensions: [kind, namespace, name]
|
|
9
|
+
measures:
|
|
10
|
+
- name: docs
|
|
11
|
+
type: count
|
|
12
|
+
extract:
|
|
13
|
+
- type: regex
|
|
14
|
+
multiline: false
|
|
15
|
+
pattern: '^kind:\s*(?P<kind>\S+)'
|
|
16
|
+
- type: regex
|
|
17
|
+
multiline: false
|
|
18
|
+
pattern: '^\s{2}namespace:\s*(?P<namespace>\S+)'
|
|
19
|
+
- type: regex
|
|
20
|
+
multiline: false
|
|
21
|
+
pattern: '^\s{2}name:\s*(?P<name>\S+)'
|
|
22
|
+
output:
|
|
23
|
+
format: flat
|
|
24
|
+
top_n: 30
|
|
25
|
+
max_lines: 80
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: loc_counter
|
|
2
|
+
description: "Lines of code by language and top-level directory. Alternative to scc/tokei/cloc for quick estimates. Splits code vs comments vs blanks."
|
|
3
|
+
scan:
|
|
4
|
+
include:
|
|
5
|
+
- "*.py"
|
|
6
|
+
- "*.js"
|
|
7
|
+
- "*.ts"
|
|
8
|
+
- "*.jsx"
|
|
9
|
+
- "*.tsx"
|
|
10
|
+
- "*.go"
|
|
11
|
+
- "*.rs"
|
|
12
|
+
- "*.java"
|
|
13
|
+
- "*.rb"
|
|
14
|
+
- "*.php"
|
|
15
|
+
- "*.kt"
|
|
16
|
+
- "*.swift"
|
|
17
|
+
- "*.c"
|
|
18
|
+
- "*.h"
|
|
19
|
+
- "*.cpp"
|
|
20
|
+
- "*.hpp"
|
|
21
|
+
- "*.cs"
|
|
22
|
+
- "*.sh"
|
|
23
|
+
- "*.sql"
|
|
24
|
+
- "*.yaml"
|
|
25
|
+
- "*.yml"
|
|
26
|
+
- "*.json"
|
|
27
|
+
- "*.md"
|
|
28
|
+
exclude: [".git/", "node_modules/", "vendor/", "dist/", "build/",
|
|
29
|
+
"target/", "*.min.*", "*.lock", "__pycache__/"]
|
|
30
|
+
dimensions: [ext, top]
|
|
31
|
+
measures:
|
|
32
|
+
- name: lines
|
|
33
|
+
type: count
|
|
34
|
+
- name: blanks
|
|
35
|
+
type: sum
|
|
36
|
+
field: blank
|
|
37
|
+
- name: comments
|
|
38
|
+
type: sum
|
|
39
|
+
field: comment
|
|
40
|
+
- name: bytes
|
|
41
|
+
type: sum
|
|
42
|
+
field: length
|
|
43
|
+
extract:
|
|
44
|
+
- type: preset
|
|
45
|
+
preset: lines
|
|
46
|
+
output:
|
|
47
|
+
format: flat
|
|
48
|
+
top_n: 50
|
|
49
|
+
min_count: 1
|
|
50
|
+
human_bytes: true
|
|
51
|
+
max_lines: 80
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: mr_impact
|
|
2
|
+
description: "MR/PR impact: distribution of changed files across top-level dir × extension with size. Feed changed files via --files-from -."
|
|
3
|
+
scan:
|
|
4
|
+
include: ["*"]
|
|
5
|
+
dimensions: [top, ext]
|
|
6
|
+
measures:
|
|
7
|
+
- name: files
|
|
8
|
+
type: count
|
|
9
|
+
- name: bytes
|
|
10
|
+
type: sum
|
|
11
|
+
field: size
|
|
12
|
+
extract:
|
|
13
|
+
- type: preset
|
|
14
|
+
preset: paths
|
|
15
|
+
output:
|
|
16
|
+
format: flat
|
|
17
|
+
top_n: 20
|
|
18
|
+
human_bytes: true
|
|
19
|
+
max_lines: 40
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: nginx_access
|
|
2
|
+
description: "Nginx combined access log: top URL sections × HTTP status with avg duration and total bytes"
|
|
3
|
+
scan:
|
|
4
|
+
include: ["access*.log*", "*.access.log*"]
|
|
5
|
+
stream: true
|
|
6
|
+
dimensions: [status, method, path_root]
|
|
7
|
+
measures:
|
|
8
|
+
- name: hits
|
|
9
|
+
type: count
|
|
10
|
+
- name: avg_dur
|
|
11
|
+
type: avg
|
|
12
|
+
field: duration
|
|
13
|
+
- name: bytes_total
|
|
14
|
+
type: sum
|
|
15
|
+
field: bytes
|
|
16
|
+
- name: max_dur
|
|
17
|
+
type: max
|
|
18
|
+
field: duration
|
|
19
|
+
extract:
|
|
20
|
+
# Combined log format + $request_time on tail; tolerates leading
|
|
21
|
+
# "[host date]" decorator (some ELB variants).
|
|
22
|
+
- type: regex
|
|
23
|
+
multiline: false
|
|
24
|
+
pattern: >-
|
|
25
|
+
(?:\[[^\]]+\]\s+)?(?P<ip>\d+\.\d+\.\d+\.\d+)\s+\S+\s+\S+\s+\[(?P<datetime>[^\]]+)\]\s+"?(?P<method>GET|POST|PUT|DELETE|HEAD|OPTIONS|PATCH)\s+/(?P<path_root>[^/?"\s]*)(?:/[^\s"?]*)?(?:\?[^\s"]*)?\s+HTTP/[\d.]+"?\s+(?P<status>\d{3})\s+(?P<bytes>\d+|-)(?:\s+"[^"]*"\s+"[^"]*")?(?:\s+"[^"]*")?(?:\s+(?P<duration>[0-9.]+|-))?
|
|
26
|
+
filters:
|
|
27
|
+
- "bytes != '-'"
|
|
28
|
+
output:
|
|
29
|
+
format: flat
|
|
30
|
+
top_n: 20
|
|
31
|
+
min_count: 5
|
|
32
|
+
human_bytes: true
|
|
33
|
+
max_lines: 60
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: nginx_cdn_covers
|
|
2
|
+
description: "CDN TSV log: /pub/c/cover_SIZE/ID.FORMAT — size × format × device with avg upstream time (port of cdn_stat.pl, no GeoIP)"
|
|
3
|
+
scan:
|
|
4
|
+
include: ["*.tsv*", "*.txt*"]
|
|
5
|
+
stream: true
|
|
6
|
+
dimensions: [size, format, device]
|
|
7
|
+
measures:
|
|
8
|
+
- name: hits
|
|
9
|
+
type: count
|
|
10
|
+
- name: avg_dur
|
|
11
|
+
type: avg
|
|
12
|
+
field: duration
|
|
13
|
+
- name: avg_upstream
|
|
14
|
+
type: avg
|
|
15
|
+
field: upstream_response_time
|
|
16
|
+
extract:
|
|
17
|
+
# Assumes tab-separated columns; picks the request cell via anchor,
|
|
18
|
+
# duration cell via the standard nginx $request_time float. `device` is
|
|
19
|
+
# derived below from the useragent match on 'Mobile'.
|
|
20
|
+
- type: regex
|
|
21
|
+
multiline: false
|
|
22
|
+
ignorecase: true
|
|
23
|
+
pattern: >-
|
|
24
|
+
GET\s+/pub/c/cover_(?P<size>\d+)/(?P<artid>\d+)\.(?P<format>webp|jpg)[^\t]*\t(?P<status>\d{3})\t(?P<duration>[0-9.]+)\t(?P<upstream_response_time>[0-9.]+|-)\t(?P<ua>[^\t]*)(?P<device>Mobile)?
|
|
25
|
+
filters:
|
|
26
|
+
- "status == 200 or status == 304"
|
|
27
|
+
- "size == 330 or size == 415"
|
|
28
|
+
output:
|
|
29
|
+
format: flat
|
|
30
|
+
top_n: 25
|
|
31
|
+
min_count: 3
|
|
32
|
+
max_lines: 80
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: openapi_endpoints
|
|
2
|
+
description: "OpenAPI/Swagger spec inventory: method × path (parses both YAML and JSON specs). Detects operationId if present."
|
|
3
|
+
scan:
|
|
4
|
+
include: ["*openapi*.yaml", "*openapi*.yml", "*openapi*.json",
|
|
5
|
+
"*swagger*.yaml", "*swagger*.yml", "*swagger*.json"]
|
|
6
|
+
dimensions: [method, path]
|
|
7
|
+
measures:
|
|
8
|
+
- name: ops
|
|
9
|
+
type: count
|
|
10
|
+
extract:
|
|
11
|
+
# match ` /path:` followed by ` get:` etc. within an indented paths: block.
|
|
12
|
+
- type: regex
|
|
13
|
+
multiline: true
|
|
14
|
+
pattern: '^\s{2,4}(?P<path>/[^\s:]+):\s*\n(?:^\s{4,6}(?P<method>get|post|put|delete|patch|options|head):)'
|
|
15
|
+
ignorecase: true
|
|
16
|
+
output:
|
|
17
|
+
format: flat
|
|
18
|
+
top_n: 40
|
|
19
|
+
max_lines: 100
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
name: react_components
|
|
2
|
+
description: "React components by type (function/class) and file"
|
|
3
|
+
scan:
|
|
4
|
+
include: ["*.jsx", "*.tsx", "*.js", "*.ts"]
|
|
5
|
+
exclude: ["node_modules/*", "*.test.*", "*.spec.*"]
|
|
6
|
+
dimensions: [type, file]
|
|
7
|
+
measures:
|
|
8
|
+
- name: count
|
|
9
|
+
type: count
|
|
10
|
+
extract:
|
|
11
|
+
- type: regex
|
|
12
|
+
pattern: '(?P<type>function|const|class)\s+(?P<name>[A-Z][a-zA-Z0-9]*)\s*[=(]'
|
|
13
|
+
output:
|
|
14
|
+
format: tree
|
|
15
|
+
min_count: 1
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: sdd_checklist
|
|
2
|
+
description: "Progress across Markdown checklists (Phase 1 gates, capability preflight, acceptance tests): file × done/todo counts"
|
|
3
|
+
scan:
|
|
4
|
+
include: ["*.md", "*.mdx"]
|
|
5
|
+
exclude: [".git/", "node_modules/"]
|
|
6
|
+
dimensions: [state, file]
|
|
7
|
+
measures:
|
|
8
|
+
- name: items
|
|
9
|
+
type: count
|
|
10
|
+
extract:
|
|
11
|
+
- type: preset
|
|
12
|
+
preset: md_checklist
|
|
13
|
+
output:
|
|
14
|
+
format: tree
|
|
15
|
+
top_n: 25
|
|
16
|
+
min_count: 1
|
|
17
|
+
max_lines: 80
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: sdd_specs
|
|
2
|
+
description: "SDD/spec-artefact inventory via YAML frontmatter: type × status per file (skills, agents, PRDs, ADRs)"
|
|
3
|
+
scan:
|
|
4
|
+
include: ["*.md", "*.mdx"]
|
|
5
|
+
exclude: [".git/", "node_modules/", "dist/"]
|
|
6
|
+
dimensions: [type, status, name]
|
|
7
|
+
measures:
|
|
8
|
+
- name: count
|
|
9
|
+
type: count
|
|
10
|
+
extract:
|
|
11
|
+
- type: preset
|
|
12
|
+
preset: md_frontmatter
|
|
13
|
+
filters:
|
|
14
|
+
# only files that had a frontmatter block
|
|
15
|
+
- "type != '---' or status != '---'"
|
|
16
|
+
output:
|
|
17
|
+
format: flat
|
|
18
|
+
top_n: 40
|
|
19
|
+
max_lines: 100
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: seo_audit
|
|
2
|
+
description: "SEO audit of a folder of HTML pages: title/description length distribution, missing/duplicate H1, canonical presence, JSON-LD schema. Feed with a site crawl or static export."
|
|
3
|
+
scan:
|
|
4
|
+
include: ["*.html", "*.htm", "*.xhtml"]
|
|
5
|
+
exclude: [".git/", "node_modules/", "dist/", "build/"]
|
|
6
|
+
dimensions: [lang, twitter_card]
|
|
7
|
+
measures:
|
|
8
|
+
- name: pages
|
|
9
|
+
type: count
|
|
10
|
+
- name: title_avg
|
|
11
|
+
type: avg
|
|
12
|
+
field: title_len
|
|
13
|
+
- name: title_max
|
|
14
|
+
type: max
|
|
15
|
+
field: title_len
|
|
16
|
+
- name: desc_avg
|
|
17
|
+
type: avg
|
|
18
|
+
field: desc_len
|
|
19
|
+
- name: h1_total
|
|
20
|
+
type: sum
|
|
21
|
+
field: h1_count
|
|
22
|
+
- name: schema_pages
|
|
23
|
+
type: sum
|
|
24
|
+
field: has_schema
|
|
25
|
+
extract:
|
|
26
|
+
- type: preset
|
|
27
|
+
preset: html_meta
|
|
28
|
+
output:
|
|
29
|
+
format: md_table
|
|
30
|
+
top_n: 40
|
|
31
|
+
max_lines: 60
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: seo_semantic_tree
|
|
2
|
+
description: "Semantic heading tree per page: file × H-level × title. Use to spot orphan H2/H3, missing H1s, unbalanced structure across a site. Render as sunburst/tree/treemap in ECharts."
|
|
3
|
+
scan:
|
|
4
|
+
include: ["*.html", "*.htm", "*.xhtml"]
|
|
5
|
+
exclude: [".git/", "node_modules/"]
|
|
6
|
+
dimensions: [file, level, title]
|
|
7
|
+
measures:
|
|
8
|
+
- name: occurrences
|
|
9
|
+
type: count
|
|
10
|
+
extract:
|
|
11
|
+
- type: preset
|
|
12
|
+
preset: html_headings
|
|
13
|
+
output:
|
|
14
|
+
format: echarts
|
|
15
|
+
chart_type: sunburst
|
|
16
|
+
top_n: 40
|
|
17
|
+
title: "Semantic heading tree"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: sitemap_map
|
|
2
|
+
description: "Sitemap.xml URL inventory: host × section (up to 3 URL segments) with priority/lastmod distribution. Supports both `<urlset>` (regular sitemaps) and `<sitemapindex>` (index files)."
|
|
3
|
+
scan:
|
|
4
|
+
include: ["sitemap*.xml", "*sitemap*.xml", "*.sitemap.xml"]
|
|
5
|
+
dimensions: [host, section_1, section_2]
|
|
6
|
+
measures:
|
|
7
|
+
- name: urls
|
|
8
|
+
type: count
|
|
9
|
+
- name: priority_avg
|
|
10
|
+
type: avg
|
|
11
|
+
field: priority
|
|
12
|
+
extract:
|
|
13
|
+
- type: preset
|
|
14
|
+
preset: sitemap
|
|
15
|
+
output:
|
|
16
|
+
format: echarts
|
|
17
|
+
chart_type: treemap
|
|
18
|
+
top_n: 100
|
|
19
|
+
min_count: 1
|
|
20
|
+
title: "Site URL taxonomy"
|