chore(agents): run audit-agent daily task — initial audit report

- Executed `scripts/check-file-size.mjs --report`
- Executed `scripts/check-innerhtml.mjs --report`
- Executed `npm run lint` (skipped assets check due to missing build)
- Created parser scripts in `scripts/agent/audit-parsers/`
- Generated JSON reports and summary in `artifacts/audit/2026-02-12/`
- Updated `AGENT_TASK_LOG.csv`

Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
google-labs-jules[bot]andPR0M3TH3AN committed 2026-02-12 21:10:13 +00:00
1 parent 8b00db23e3
commit fab5b11824
12 files changed
+756 -23

No files matched your search

@@ -0,0 +1,61 @@
import json
import re
import sys
def parse_file_size_log(filepath):
"""
Parses check-file-size.mjs raw output.
"""
try:
with open(filepath, 'r') as f:
content = f.read()
except FileNotFoundError:
print(f"Error: File not found: {filepath}", file=sys.stderr)
return {}
metrics = {
"grandfathered_files": 0,
"grandfathered_excess_lines": 0,
"new_oversized_files": 0,
"new_excess_lines": 0,
"grandfathered_list": [],
"new_list": [],
}
# Match "grandfathered" lines
# Example: " ⚠ grandfathered: js/adminListStore.js (1033 lines)"
grandfathered_matches = re.findall(r"⚠ grandfathered: (.+?) \((\d+) lines\)", content)
for path, lines in grandfathered_matches:
metrics["grandfathered_files"] += 1
excess = int(lines) - 1000 # Default threshold
metrics["grandfathered_excess_lines"] += excess
metrics["grandfathered_list"].append({"path": path, "lines": int(lines), "excess": excess})
# Match "violations" (new files)
# Example: " ✗ NEW: js/newfile.js (1200 lines, threshold 1000)"
new_matches = re.findall(r"✗ NEW: (.+?) \((\d+) lines, threshold (\d+)\)", content)
for path, lines, threshold in new_matches:
metrics["new_oversized_files"] += 1
excess = int(lines) - int(threshold)
metrics["new_excess_lines"] += excess
metrics["new_list"].append({"path": path, "lines": int(lines), "excess": excess})
# Match "GREW" violations (grandfathered growing)
# Example: " ✗ GREW: js/file.js (1200 lines, was 1100, limit 1150)"
grew_matches = re.findall(r"✗ GREW: (.+?) \((\d+) lines, was (\d+), limit (\d+)\)", content)
for path, lines, was, limit in grew_matches:
metrics["new_oversized_files"] += 1 # Count as a violation
excess = int(lines) - int(limit) # Or relative to original? Let's use diff
metrics["new_excess_lines"] += excess
metrics["new_list"].append({"path": path, "lines": int(lines), "excess": excess, "type": "GREW"})
return metrics
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python parse_file_size.py <logfile>")
sys.exit(1)
filepath = sys.argv[1]
metrics = parse_file_size_log(filepath)
print(json.dumps(metrics, indent=2))
@@ -0,0 +1,57 @@
import json
import re
import sys
def parse_innerhtml_log(filepath):
"""
Parses check-innerhtml.mjs raw output.
"""
try:
with open(filepath, 'r') as f:
content = f.read()
except FileNotFoundError:
print(f"Error: File not found: {filepath}", file=sys.stderr)
return {}
metrics = {
"total_assignments": 0,
"files_count": 0,
"top_offenders": [],
"violations": []
}
# Match total summary
# Example: "innerHTML usage: 87 assignments across 34 files"
summary_match = re.search(r"innerHTML usage: (\d+) assignments across (\d+) files", content)
if summary_match:
metrics["total_assignments"] = int(summary_match.group(1))
metrics["files_count"] = int(summary_match.group(2))
# Match individual file usage
# Example: " js/channelProfile.js: 10" or " js/file.js: 5 ← NEW"
usage_matches = re.findall(r"^\s+([^\s:]+): (\d+)( ← NEW)?", content, re.MULTILINE)
for path, count, is_new in usage_matches:
metrics["top_offenders"].append({"path": path, "count": int(count), "is_new": bool(is_new)})
# Match violations (enforce mode output)
# Example: " ✗ js/file.js: 5 total (baseline 3, +2 new) at line(s) 10, 20"
violation_matches = re.findall(r"✗ ([^:]+): (\d+) total \(baseline (\d+), \+(\d+) new\) at line\(s\) (.+)", content)
for path, total, baseline, new, lines in violation_matches:
metrics["violations"].append({
"path": path,
"total": int(total),
"baseline": int(baseline),
"new": int(new),
"lines": lines
})
return metrics
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python parse_innerhtml.py <logfile>")
sys.exit(1)
filepath = sys.argv[1]
metrics = parse_innerhtml_log(filepath)
print(json.dumps(metrics, indent=2))
+58
View File
@@ -0,0 +1,58 @@
import json
import re
import sys
def parse_lint_log(filepath):
"""
Parses npm run lint raw output.
"""
try:
with open(filepath, 'r') as f:
content = f.read()
except FileNotFoundError:
print(f"Error: File not found: {filepath}", file=sys.stderr)
return {}
metrics = {
"total_failures": 0,
"files_with_errors": [],
"skipped_checks": []
}
# Looking for typical npm error outputs or specific linter errors.
# Since we are running `npm run lint` which chains multiple commands, failure results in `npm ERR!`.
# Check if the process exited with error (usually indicated by npm ERR!)
if "npm ERR!" in content:
metrics["total_failures"] = 1 # At least one failure
# Check for specific skipped checks
# Example: "[lint:assets] Missing dist/asset-manifest.json. Skipping asset reference check (build required)."
skipped_matches = re.findall(r"\[(.+?)\] (.+?) Skipping (.+)", content)
for check_name, reason, details in skipped_matches:
metrics["skipped_checks"].append({
"check": check_name,
"reason": reason.strip(),
"details": details.strip()
})
# Check for stylelint errors
# Example: "css/source.css\n 10:5 × Unexpected unknown property "foo" property-no-unknown"
# This is hard to parse generally without JSON output, but we can look for "×" or "error" lines.
# Count "problems" from eslint/stylelint if standard format
# "3 problems (3 errors, 0 warnings)"
problem_matches = re.findall(r"(\d+) problems? \((\d+) errors?, (\d+) warnings?\)", content)
for problems, errors, warnings in problem_matches:
metrics["total_failures"] += int(errors)
return metrics
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python parse_lint.py <logfile>")
sys.exit(1)
filepath = sys.argv[1]
metrics = parse_lint_log(filepath)
print(json.dumps(metrics, indent=2))
@@ -0,0 +1,99 @@
import json
import sys
import datetime
def load_json(filepath):
try:
with open(filepath, 'r') as f:
return json.load(f)
except FileNotFoundError:
return {}
def generate_summary(file_size_path, innerhtml_path, lint_path, date_str):
file_size = load_json(file_size_path)
innerhtml = load_json(innerhtml_path)
lint = load_json(lint_path)
lines = []
lines.append(f"Title: Audit Report — {date_str} (unstable)")
lines.append("")
lines.append("**Summary**")
lines.append("")
lines.append(f"* Date: {date_str}")
lines.append("* Branch: unstable")
lines.append("")
lines.append("**Metrics**")
lines.append("")
# File Size
gf_files = file_size.get("grandfathered_files", 0)
gf_excess = file_size.get("grandfathered_excess_lines", 0)
new_files = file_size.get("new_oversized_files", 0)
new_excess = file_size.get("new_excess_lines", 0)
lines.append(f"* Grandfathered oversized files: {gf_files} files (total excess lines: {gf_excess})")
lines.append(f"* New oversized files: {new_files} files (total excess lines: {new_excess})")
# InnerHTML
total_assign = innerhtml.get("total_assignments", 0)
files_count = innerhtml.get("files_count", 0)
lines.append(f"* Total innerHTML assignments: {total_assign} across {files_count} files")
lines.append("")
lines.append(" * Top offenders:")
lines.append("")
top_offenders = innerhtml.get("top_offenders", [])
# Sort by count desc
top_offenders.sort(key=lambda x: x["count"], reverse=True)
for i, offender in enumerate(top_offenders[:10]):
status = " (NEW)" if offender.get("is_new") else ""
lines.append(f" {i+1}. {offender['path']} — {offender['count']}{status}")
# Lint
lint_failures = lint.get("total_failures", 0)
lint_skipped = lint.get("skipped_checks", [])
lines.append("")
lines.append(f"* Lint failures: {lint_failures}")
if lint_skipped:
lines.append(f"* Skipped checks: {len(lint_skipped)}")
for skip in lint_skipped:
lines.append(f" * {skip['check']}: {skip['reason']}")
lines.append("")
lines.append("**High-priority items**")
lines.append("")
if new_files > 0:
for f in file_size.get("new_list", []):
lines.append(f"* Remove or trim oversized file `{f['path']}` (excess lines: {f['excess']})")
violations = innerhtml.get("violations", [])
if violations:
for v in violations:
lines.append(f"* Review `{v['path']}` for new innerHTML usage (+{v['new']})")
if lint_failures > 0:
lines.append(f"* Fix lint errors (see logs)")
if not (new_files > 0 or violations or lint_failures > 0):
lines.append("* None. Keep it up!")
lines.append("")
lines.append("**Artifacts**")
lines.append("")
lines.append("* file-size-report.json")
lines.append("* innerhtml-report.json")
lines.append("* lint-report.json")
lines.append("* raw logs")
return "\n".join(lines)
if __name__ == "__main__":
if len(sys.argv) < 5:
print("Usage: python generate_summary.py <file-size-json> <innerhtml-json> <lint-json> <date>")
sys.exit(1)
summary = generate_summary(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
print(summary)