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.
Files changed (46) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +27 -0
  3. package/README.ar.md +110 -0
  4. package/README.bn.md +111 -0
  5. package/README.es.md +110 -0
  6. package/README.hi.md +110 -0
  7. package/README.ja.md +113 -0
  8. package/README.md +469 -0
  9. package/README.pa.md +114 -0
  10. package/README.pt.md +113 -0
  11. package/README.ru.md +1174 -0
  12. package/README.zh-CN.md +233 -0
  13. package/bin/cubest.js +28 -0
  14. package/cubest.py +1862 -0
  15. package/package.json +28 -0
  16. package/profiles/agents_inventory.yaml +15 -0
  17. package/profiles/api_routes.yaml +20 -0
  18. package/profiles/call_graph.yaml +19 -0
  19. package/profiles/code_atlas.yaml +33 -0
  20. package/profiles/code_stats.yaml +15 -0
  21. package/profiles/csv_analytics.yaml +31 -0
  22. package/profiles/disk_usage.yaml +29 -0
  23. package/profiles/doc_structure.yaml +16 -0
  24. package/profiles/file_tree.yaml +27 -0
  25. package/profiles/frontend_geoip.yaml +49 -0
  26. package/profiles/git_log_activity.yaml +29 -0
  27. package/profiles/imports.yaml +16 -0
  28. package/profiles/jsonl_events.yaml +19 -0
  29. package/profiles/k8s_resources.yaml +25 -0
  30. package/profiles/loc_counter.yaml +51 -0
  31. package/profiles/mr_impact.yaml +19 -0
  32. package/profiles/nginx_access.yaml +33 -0
  33. package/profiles/nginx_cdn_covers.yaml +32 -0
  34. package/profiles/openapi_endpoints.yaml +19 -0
  35. package/profiles/react_components.yaml +15 -0
  36. package/profiles/sdd_checklist.yaml +17 -0
  37. package/profiles/sdd_specs.yaml +19 -0
  38. package/profiles/seo_audit.yaml +31 -0
  39. package/profiles/seo_semantic_tree.yaml +17 -0
  40. package/profiles/sitemap_map.yaml +20 -0
  41. package/profiles/skills_inventory.yaml +17 -0
  42. package/profiles/spec_status.yaml +18 -0
  43. package/profiles/sql_functions.yaml +31 -0
  44. package/profiles/tech_debt.yaml +16 -0
  45. package/profiles/xml_tags.yaml +21 -0
  46. 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"