ci: add .mjs to check-comment-blocks.sh + check-issue-refs.sh's scope

mara: "add mjs to the lint and fix it in this pr". Both lints scope their
git ls-files scan to a fixed extension list that never included .mjs, so
all three frontend build.mjs files (swarm-ui, dashboard, agent) were
completely invisible to both -- not merely under the limits, outside the
scan entirely.

check-comment-blocks.sh: added '*.mjs' to the ls-files glob and to the
mode_of regex (same slash-comment treatment .js/.ts/.tsx already get --
.mjs is the same comment syntax, argus's exact proposed fix). check-issue-refs.sh:
added '*.mjs' to its glob list, no regex change needed.

Fixing the scope immediately surfaced real, pre-existing violations in
the other two build.mjs files (swarm-ui's own is already handled by this
PR's earlier commits):
- dashboard/build.mjs: 49-line comment block (trimmed to 15 -- redundant
  per-file output-layout table cut, the code below already names every
  output path) plus three bare tracker tags (#448 x2, #453) in the
  stream-worker comment, reworded to prose
- agent/build.mjs: two bare tracker tags (hyperhive#3685 x2), reworded

No logic changes anywhere -- comment-only edits plus the two lint
scripts. Closes #4300 and (independently filed, consolidated into that
one) #4299.
This commit is contained in:
iris 2026-09-12 12:17:50 +02:00 committed by mara
commit 3c6c2ed272
4 changed files with 24 additions and 59 deletions

View file

@ -1,7 +1,7 @@
// esbuild build for @hive/agent. Output layout (`dist/`): // esbuild build for @hive/agent. Output layout (`dist/`):
// //
// dist/index.html served at GET / (the Preact rewrite, // dist/index.html served at GET / (the Preact rewrite
// hyperhive#3685 — app.js is deleted) // the old vanilla-JS app.js is deleted)
// dist/stats.html served at GET /stats // dist/stats.html served at GET /stats
// dist/screen.html served at GET /screen // dist/screen.html served at GET /screen
// dist/static/stats.js served at /static/stats.js (pulls in // dist/static/stats.js served at /static/stats.js (pulls in
@ -50,7 +50,7 @@ await build({
loader: { ".css": "text" }, loader: { ".css": "text" },
}); });
// The main agent page (hyperhive#3685's Preact rewrite — app.js, // The main agent page (the Preact rewrite — the old vanilla-JS app.js,
// which used to share this build step, is deleted). A separate bundle // which used to share this build step, is deleted). A separate bundle
// from stats.js above rather than folded in: different loader needs // from stats.js above rather than folded in: different loader needs
// (`.css: 'css'`, real stylesheets a component imports, vs. the raw- // (`.css: 'css'`, real stylesheets a component imports, vs. the raw-

View file

@ -1,52 +1,18 @@
// esbuild build for @hive/dashboard. Output layout (`dist/`): // esbuild build for @hive/dashboard: one JS+CSS bundle per page (H0M3 at
// // `/`, dashboard/flow/logs/core/builds/credentials at their own
// dist/index.html H0M3 menu hub — served by the Rust // `.html`), each named after its own entry point below — see the
// router at GET / (the landing page) // `entryPoints`/`for` lists for the exact map, not repeated here to
// dist/dashboard.html the operator dashboard SPA — served // avoid this comment drifting out of sync with the real build steps.
// at GET /dashboard.html
// dist/flow.html served at GET /flow.html
// dist/logs.html served at GET /logs.html (AGENT/INFRA/SYSTEM)
// dist/core.html served at GET /core.html (C0R3: kept
// state / container load)
// dist/builds.html served at GET /builds.html (BU1LDS:
// rebuild queue / meta inputs / build logs)
// dist/credentials.html served at GET /credentials.html
// (CR3D3NTIALS: matrix + github accounts)
// dist/static/home.js index.html (H0M3) entry — menu tiles +
// matrix-tile gating + identity line
// dist/static/tabs.js dashboard.html entry — tab renderers +
// tab routing + refreshState
// dist/static/flow.js /flow.html entry — broker terminal +
// @-mention composer
// dist/static/logs.js /logs.html entry — agent/infra/system
// log viewer sub-tabs
// dist/static/builds.js /builds.html entry — rebuild queue,
// meta inputs, build log history
// dist/static/credentials.js /credentials.html entry — matrix +
// github account sub-tabs
// dist/static/{home,tabs,flow,logs,builds,credentials}.js.map source map
// siblings
// dist/static/common.css loaded by every page (@hive/shared
// imports + shared typography/badges/
// buttons/inbox/side-panel)
// dist/static/dashboard.css dashboard.html only (dashboard-specific)
// dist/static/flow.css /flow.html only (flow chrome + composer)
// dist/static/logs.css /logs.html only (log viewer sub-tabs)
// dist/static/builds.css /builds.html only (build lifecycle hub)
// dist/static/home.css index.html (H0M3) only (tile grid)
// dist/static/credentials.css /credentials.html only (matrix + github
// account forms)
// //
// Each JS entry bundles `./common.js` (DOM helpers, Panel singleton, // Each JS entry bundles `./common.js` (DOM helpers, Panel singleton,
// NOTIF, path linkification) independently — esbuild inlines the shared // NOTIF, path linkification) independently — esbuild inlines the shared
// module into each bundle rather than emitting a shared chunk (no // module into each bundle rather than emitting a shared chunk (no
// `splitting: true`). The Rust binary mounts `dist/` as a // `splitting: true`). The Rust binary mounts `dist/` as a
// `tower_http::ServeDir` fallback (`append_index_html_on_directories` // `tower_http::ServeDir` fallback (`append_index_html_on_directories`
// serves index.html at /); the layout above keeps every URL the HTML // serves index.html at /); the dashboard SPA lives at /dashboard.html
// files reference reachable without rewriting paths in the HTML. The // (a plain file, not a /dashboard/ prefix) so it never shadows the
// dashboard SPA lives at /dashboard.html (a plain file, not a /dashboard/ // exact-match /dashboard/stream + /dashboard/history SSE routes
// prefix) so it never shadows the exact-match /dashboard/stream + // registered before the ServeDir fallback.
// /dashboard/history SSE routes registered before the ServeDir fallback.
import { build } from "esbuild"; import { build } from "esbuild";
import { mkdirSync, copyFileSync, rmSync } from "node:fs"; import { mkdirSync, copyFileSync, rmSync } from "node:fs";
@ -102,18 +68,17 @@ await build({
jsxImportSource: "preact", jsxImportSource: "preact",
}); });
// Stream-worker entry (#448). Lives in a separate bundle: SharedWorker // Stream-worker entry. Lives in a separate bundle: SharedWorker
// scripts run in a different global (`self` is the worker scope, no // scripts run in a different global (`self` is the worker scope, no
// `window`) so they can't be inlined into tabs.js / flow.js. Output is // `window`) so they can't be inlined into tabs.js / flow.js. Output is
// at `static/stream-worker.js`; common.js's `openStream` references // at `static/stream-worker.js`; common.js's `openStream` references
// `/static/stream-worker.js` as the SharedWorker URL. `format: 'iife'` // `/static/stream-worker.js` as the SharedWorker URL. `format: 'iife'`
// matches the classic-script load (`new SharedWorker(url, name)` with // matches the classic-script load (`new SharedWorker(url, name)` with
// no `{ type: 'module' }`); Firefox is the #448 target and module // no `{ type: 'module' }`); Firefox's module SharedWorker support is
// SharedWorker support there is patchy, so keeping the worker as a // patchy, so keeping the worker as a classic script + IIFE bundle is
// classic script + IIFE bundle is the compatible default. argus nit // the compatible default. argus's own review nit here: if a future
// on #453: if a future contributor adds an `import` to this bundle, // contributor adds an `import` to this bundle, the IIFE format will
// the IIFE format will surface it as a build error rather than // surface it as a build error rather than silently shipping broken code.
// silently shipping broken code.
await build({ await build({
entryPoints: [src("stream-worker.js")], entryPoints: [src("stream-worker.js")],
outdir: staticDir(""), outdir: staticDir(""),

View file

@ -8,7 +8,7 @@
# exceeds MAX. Runs as its own CI job and IS a required check on the forge # exceeds MAX. Runs as its own CI job and IS a required check on the forge
# (branch protection) — a hit blocks merge. # (branch protection) — a hit blocks merge.
# #
# Scope: tracked *.rs *.nix *.sh *.js *.ts *.tsx *.css *.html. Markdown is exempt # Scope: tracked *.rs *.nix *.sh *.js *.mjs *.ts *.tsx *.css *.html. Markdown is exempt
# (it is prose by nature). Comment forms: `#` line comments (nix/sh), `//` # (it is prose by nature). Comment forms: `#` line comments (nix/sh), `//`
# line comments (rs/js/ts), and `/* */` block comments (nix/rs/js/ts/css) + # line comments (rs/js/ts), and `/* */` block comments (nix/rs/js/ts/css) +
# `<!-- -->` (html). A blank line separates two line-comment blocks (does NOT # `<!-- -->` (html). A blank line separates two line-comment blocks (does NOT
@ -23,12 +23,12 @@ MAX=30
# Collect annotations into a variable (not via xargs/awk exit codes) so a # Collect annotations into a variable (not via xargs/awk exit codes) so a
# hit in any xargs batch is preserved — mirrors scripts/check-issue-refs.sh. # hit in any xargs batch is preserved — mirrors scripts/check-issue-refs.sh.
hits="$( hits="$(
git ls-files -z '*.rs' '*.nix' '*.sh' '*.js' '*.ts' '*.tsx' '*.css' '*.html' \ git ls-files -z '*.rs' '*.nix' '*.sh' '*.js' '*.mjs' '*.ts' '*.tsx' '*.css' '*.html' \
| xargs -0 -r awk -v MAX="$MAX" ' | xargs -0 -r awk -v MAX="$MAX" '
function mode_of(fn) { function mode_of(fn) {
if (fn ~ /\.nix$/) return "nix" if (fn ~ /\.nix$/) return "nix"
if (fn ~ /\.sh$/) return "hash" if (fn ~ /\.sh$/) return "hash"
if (fn ~ /\.(rs|js|ts|tsx)$/) return "slash" if (fn ~ /\.(rs|js|mjs|ts|tsx)$/) return "slash"
if (fn ~ /\.css$/) return "cstyle" if (fn ~ /\.css$/) return "cstyle"
if (fn ~ /\.html$/) return "html" if (fn ~ /\.html$/) return "html"
return "" return ""

View file

@ -11,8 +11,8 @@
# Emits a CI error annotation per hit, exits 1 if any hit is found. Its own # Emits a CI error annotation per hit, exits 1 if any hit is found. Its own
# required CI job (branch protection) — a hit blocks merge. # required CI job (branch protection) — a hit blocks merge.
# #
# Scope: every tracked `*.rs *.nix *.js *.ts *.tsx *.css *.html *.md *.yml # Scope: every tracked `*.rs *.nix *.js *.mjs *.ts *.tsx *.css *.html *.md
# *.yaml`. CI workflow files (`.forgejo/workflows/*.yml`) are explicitly in # *.yml *.yaml`. CI workflow files (`.forgejo/workflows/*.yml`) are explicitly in
# scope: a step comment is still a comment. The pattern matches a hash, # scope: a step comment is still a comment. The pattern matches a hash,
# 2-5 digits, then a non-alphanumeric char or end-of-line (skips # 2-5 digits, then a non-alphanumeric char or end-of-line (skips
# letter-bearing hex colours and digit-runs-then-letter, e.g. `#24h`; # letter-bearing hex colours and digit-runs-then-letter, e.g. `#24h`;
@ -33,7 +33,7 @@ pattern='#[0-9]{2,5}([^0-9a-zA-Z]|$)|/issues/[0-9]+([^0-9a-zA-Z]|$)'
# an empty file list. Lines carrying the `lint:allow` marker are dropped # an empty file list. Lines carrying the `lint:allow` marker are dropped
# (legitimate non-tracker hit; see the header). # (legitimate non-tracker hit; see the header).
hits="$( hits="$(
git ls-files -z '*.rs' '*.nix' '*.js' '*.ts' '*.tsx' '*.css' '*.html' '*.md' \ git ls-files -z '*.rs' '*.nix' '*.js' '*.mjs' '*.ts' '*.tsx' '*.css' '*.html' '*.md' \
'*.yml' '*.yaml' \ '*.yml' '*.yaml' \
| xargs -0 -r grep -nE "$pattern" /dev/null 2>/dev/null \ | xargs -0 -r grep -nE "$pattern" /dev/null 2>/dev/null \
| grep -v 'lint:allow' || true | grep -v 'lint:allow' || true