Skip to content

feat: Performance v0.4 — static <img> checks + multi-category foundation (#10) - #36

Merged
oekazuma merged 14 commits into
mainfrom
feat/performance-v0.4
Jun 22, 2026
Merged

oekazuma merged 14 commits into
mainfrom
feat/performance-v0.4

Conversation

@oekazuma

@oekazuma oekazuma commented Jun 22, 2026 •

Copy link
Copy Markdown
Owner

First Vitals category beyond SEO, plus the multi-category foundation later categories reuse. Implements the Performance v0.4 item of #10 (static-analysis only; no runtime Core Web Vitals).

What's new

  • PERF001 — image dimensions (warning): an <img> missing explicit width/height (CLS risk). A dynamically-bound dimension (width={w}) counts as present and passes.
  • PERF002 — image loading hint (info): an <img> with no loading attribute (advisory; static analysis can't know the LCP image, so it never fails the build).
  • One finding per offending <img>, with location (file) + line.

Multi-category foundation

  • Result.category + line; image IR (ImageInfo/ResolvedImages) + RuleContext.images; an imageRule factory.
  • scoresByCategory — per-category scores by reusing the existing route-average computeScore.
  • Category-aware reporters: console shows a per-category score line (SEO Score: / Performance Score:); json adds a categories map and tags issues with category/line; agent uses a category-neutral heading; github/sarif carry the finding line.
  • CLI provider collects heads and <img> in a single walk of each route's layout chain (collectRoutes) — one read + parse per file (a layout image surfaces per child route, like inherited head findings).

Additivity

The change is additive: a missing category defaults to 'seo', the json top-level score stays the SEO subset, and the Performance reporting only adds sections. All existing SEO findings, scores, and output are unchanged.

Scope

Static mode only; @svelte-vitals/vite untouched. Per #10's plan and the 1.0 philosophy, preload/adapter/large-import checks, plugin-mode images, and the combined weighted Health Report are later 0.x increments (1.0 is the polished culmination, not where new integration lands).

Validation

  • pnpm -r test — 240 passed (core 89, vite 31, cli 111, mcp 9)
  • pnpm -r typecheck, pnpm build, pnpm lint, publint + attw (esm-only) — green

Notes for reviewers

  • Built subagent-driven: 6 tasks, each spec+quality reviewed, plus a whole-branch review.
  • Performance category only appears when the project has <img> elements. PERF rules emit nothing for an image-less route, so a zero-image project hides the Performance section entirely (rather than reporting a hollow Performance Score: 100/100), and the console Passed list is no longer padded with per-route PERF passes for image-less routes. Routes whose images all pass still seed a 100 for the per-category score.
  • SARIF partialFingerprints are disambiguated by line (and location) so multiple per-route image findings don't collapse into one code-scanning alert (SEO fingerprints unchanged).

Review follow-up (addressed in this branch)

  • Single-pass collection — heads and images are now gathered in one walk of each route's layout chain (collectRoutes), parsing every .svelte file once instead of twice (the head and image providers previously each walked + parsed the whole chain independently).
  • Image-less routes — no longer emit passing seeds (the zero-image behavior described above).
  • Console header tidied to Svelte Vitals · <mode>; the unused _config parameter was removed by the single-pass refactor.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added Performance category with image-dimension checks (width/height) and loading attribute advisories
    • Multi-category reporting system now groups findings by category with independent per-category scores
    • Category-aware output in console, JSON, GitHub, and SARIF reporters
  • Documentation

    • Updated roadmap reflecting Performance v0.4 and upcoming categories before v1.0 release

oekazuma and others added 10 commits June 22, 2026 17:11
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ings (#10)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 22, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@oekazuma, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 5 minutes and 3 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c0032080-0a5d-42a0-9549-5591af9dde38

📥 Commits

Reviewing files that changed from the base of the PR and between 64d8023 and a787959.

📒 Files selected for processing (12)
  • docs/superpowers/specs/2026-06-22-performance-v0.4-design.md
  • packages/cli/src/index.ts
  • packages/cli/src/providers/source/parse.ts
  • packages/cli/src/providers/source/routes.ts
  • packages/cli/test/parse-file.test.ts
  • packages/cli/test/source-provider.test.ts
  • packages/core/src/reporter/console.ts
  • packages/core/src/reporter/sarif.ts
  • packages/core/src/rules/perf/image-rule.ts
  • packages/core/test/perf-rules.test.ts
  • packages/core/test/sarif-report.test.ts
  • packages/vite/test/analyze.test.ts
📝 Walkthrough

Walkthrough

Adds a Performance analysis category to svelte-vitals (v0.4) with two static <img> rules: PERF001 (missing width/height, warning) and PERF002 (missing loading, informational). Introduces ImageInfo/ResolvedImages data contracts, a generic imageRule factory, per-category scoring via scoresByCategory, CLI AST image parsing, and category-aware updates to all reporters.

Changes

Performance v0.4 — image analysis and multi-category reporting

Layer / File(s) Summary
Core data contracts: Result, ImageInfo, RuleContext
packages/core/src/types.ts, packages/core/src/images.ts, packages/core/src/rule.ts, packages/core/src/index.ts
Result gains optional category and line fields; new ImageInfo and ResolvedImages interfaces model normalized <img> elements; RuleContext adds optional images?: ResolvedImages[].
imageRule factory, PERF001/PERF002 rules, SEO category tagging, registry
packages/core/src/rules/perf/image-rule.ts, packages/core/src/rules/perf/images.ts, packages/core/src/rules/seo/head-tag-rule.ts, packages/core/src/rules/seo/project-rules.ts, packages/core/src/rules/seo/seo001-title.ts, packages/core/src/rules/index.ts, packages/core/src/index.ts
Generic imageRule factory builds route-scoped image rules; perf001ImageDimensions and perf002ImageLoading are defined via that factory; all existing SEO rule results are tagged with category: 'seo'; both new rules are registered in allRules and re-exported.
Per-category scoring via scoresByCategory
packages/core/src/scoring/score.ts
New exported scoresByCategory partitions results by category (defaulting to seo) and returns per-category ScoreResult objects.
CLI image AST parsing and route image provider
packages/cli/src/providers/source/parse.ts, packages/cli/src/providers/source/routes.ts, packages/cli/src/index.ts, packages/cli/test/fixtures/basic-project/src/routes/img/+page.svelte
parseFile gains collectImages AST traversal and a lineOf helper, populating ParsedFile.images; sourceImageProvider walks the layout chain to produce ResolvedImages[]; analyzeProject threads images into runRules; a fixture page with a bare <img> is added for e2e testing.
Category-aware reporter updates
packages/core/src/reporter/console.ts, packages/core/src/reporter/agent.ts, packages/core/src/reporter/json.ts, packages/core/src/reporter/github.ts, packages/core/src/reporter/sarif.ts
Console reporter computes per-category score sections and appends :line to locations; agent heading becomes category-neutral; JSON gains a categories map while preserving the top-level SEO score; GitHub annotations conditionally emit file= and line=; SARIF adds region.startLine and includes line in partialFingerprints.
Core unit tests: perf rules, scoring, reporters, rule-category
packages/core/test/perf-rules.test.ts, packages/core/test/rule-category.test.ts, packages/core/test/score.test.ts, packages/core/test/console-report.test.ts, packages/core/test/agent-report.test.ts, packages/core/test/json-report.test.ts, packages/core/test/github-report.test.ts, packages/core/test/sarif-report.test.ts
New test suites cover PERF001/PERF002 semantics, scoresByCategory category independence and defaulting, SEO rule category tagging, and all reporter behavior changes (performance score section, neutral heading, JSON categories, GitHub line annotation, SARIF region/fingerprint).
CLI integration tests and vite test update
packages/cli/test/parse-file.test.ts, packages/cli/test/source-provider.test.ts, packages/cli/test/run.test.ts, packages/vite/test/analyze.test.ts
Adds parse-file tests for <img> attribute detection including dynamic bindings, source-provider in-memory tests for layout image inheritance, e2e run test asserting PERF001 appears in JSON output for /img route, and updates agent heading and vite plugin console label assertions.
Spec, implementation plan, README roadmap, and changeset
docs/superpowers/specs/2026-06-22-performance-v0.4-design.md, docs/superpowers/plans/2026-06-22-performance-v0.4.md, README.md, .changeset/performance-v0.4.md
Design spec and implementation plan for Performance v0.4; README roadmap updated with shipped Performance checks at 0.4 and revised upcoming milestones; changeset documents minor version bumps.

Sequence Diagram(s)

sequenceDiagram
  participant CLI as analyzeProject
  participant ImageProv as sourceImageProvider
  participant Parser as parseFile (AST)
  participant Core as runRules
  participant Reporters as console/json/sarif/github/agent

  CLI->>ImageProv: collect(rt, cwd, config)
  ImageProv->>Parser: read + parse +page.svelte & layouts
  Parser-->>ImageProv: ParsedFile { images: ParsedImage[] }
  ImageProv-->>CLI: ResolvedImages[] (per route)
  CLI->>Core: runRules({ heads, images, project, config })
  Core->>Core: imageRule → PERF001 / PERF002 checks
  Core-->>CLI: Result[] with category + line
  CLI->>Reporters: formatConsoleReport / buildJsonReport / formatSarifReport
  Reporters->>Reporters: scoresByCategory(results) → per-category scores
  Reporters-->>CLI: category-aware output with Performance section
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

Possibly related PRs

  • oekazuma/svelte-vitals#22: Both PRs modify the SARIF and GitHub Actions reporters — the referenced PR originally introduced those reporters; this PR extends them with category/line-aware output.

Poem

🐰 Hop, hop — images beware!
No width or height? PERF001 is there.
Missing loading? PERF002 will say.
Categories bloom like fields in May.
The rabbit scores SEO and perf with glee,
A multi-category world for all to see! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 65.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: Performance v0.4 — static checks + multi-category foundation (#10)' directly and comprehensively summarizes the main changes: introducing Performance v0.4 rules for static image checking and establishing the multi-category foundation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/performance-v0.4

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
packages/cli/src/index.ts (1)

90-92: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Parallelize provider collection to reduce analysis latency.

Line 90 and Line 91 run head/image collection sequentially. Running them concurrently removes unnecessary wait time on larger projects.

♻️ Suggested change
-  const heads = (await sourceHeadProvider.collect(rt, cwd, config)).filter((h) => matches(h.route));
-  const images = (await sourceImageProvider.collect(rt, cwd, config)).filter((i) => matches(i.route));
+  const [allHeads, allImages] = await Promise.all([
+    sourceHeadProvider.collect(rt, cwd, config),
+    sourceImageProvider.collect(rt, cwd, config)
+  ]);
+  const heads = allHeads.filter((h) => matches(h.route));
+  const images = allImages.filter((i) => matches(i.route));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/src/index.ts` around lines 90 - 92, The
sourceHeadProvider.collect and sourceImageProvider.collect calls on lines 90-91
are executed sequentially, creating unnecessary wait time. Refactor these two
lines to run concurrently by using Promise.all to invoke both collect methods in
parallel, then apply the filter operations to each result. This allows both
providers to collect data simultaneously instead of waiting for one to complete
before starting the other.
packages/core/src/rule.ts (1)

5-9: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Update stale RuleContext doc comment to reflect images support.

Line 5 still states rules only see ResolvedHead[], but Line 9 adds images?: ResolvedImages[]. Keeping this comment accurate prevents API misunderstanding for rule implementers.

Suggested patch
-/** Input given to every rule. Mode-independent: rules see only ResolvedHead[] (design §8, §10). */
+/** Input given to every rule. Mode-independent shape shared across rule categories. */
 export interface RuleContext {
   heads: ResolvedHead[];
   /** Per-route <img> elements for Performance rules (absent in modes that don't collect them). */
   images?: ResolvedImages[];
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/rule.ts` around lines 5 - 9, The JSDoc comment for the
RuleContext interface states that rules only see ResolvedHead[], but the
interface now also includes an optional images field. Update the comment above
the RuleContext interface definition to accurately reflect that rules receive
both a heads field and an optional images field for Performance rules, making it
clear that the interface is no longer mode-independent in the way the current
comment suggests.
packages/core/test/agent-report.test.ts (1)

51-51: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Tighten the heading assertion to actually catch SEO-specific regressions.

/^# svelte-vitals/m will still pass if the heading reverts to something like # svelte-vitals — SEO fixes. Assert the exact expected heading.

Suggested test update
-    expect(md).toMatch(/^# svelte-vitals/m); // heading no longer says "SEO fixes"
+    expect(md).toContain('# svelte-vitals — fixes');
+    expect(md).not.toContain('SEO fixes');
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/test/agent-report.test.ts` at line 51, The regex assertion in
the test at the expect(md).toMatch() call is too permissive and will pass even
if the heading reverts to including "SEO fixes". Instead of using the partial
match regex /^# svelte-vitals/m, make the assertion more specific by matching
the exact expected heading format so that any regression where "SEO fixes" gets
added back to the heading will cause the test to fail.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/src/reporter/sarif.ts`:
- Around line 50-52: The partialFingerprints fingerprint construction for the
'svelteVitals/v1' key is missing location information, which allows distinct
findings from different files with the same route and line to collide. Update
the template string that builds the fingerprint value to include the location
field (r.location) in the fingerprint key construction so that findings remain
distinct across different files.

In `@packages/core/src/rules/perf/image-rule.ts`:
- Around line 55-57: The result object in the findings emission always includes
line: img.line regardless of whether img.line is a valid 1-based line number.
The line field in Result is optional and should only be included when img.line
is greater than 0 (valid). Modify the result object construction to
conditionally include the line property only when img.line is a valid positive
number, otherwise omit it entirely from the object.

---

Nitpick comments:
In `@packages/cli/src/index.ts`:
- Around line 90-92: The sourceHeadProvider.collect and
sourceImageProvider.collect calls on lines 90-91 are executed sequentially,
creating unnecessary wait time. Refactor these two lines to run concurrently by
using Promise.all to invoke both collect methods in parallel, then apply the
filter operations to each result. This allows both providers to collect data
simultaneously instead of waiting for one to complete before starting the other.

In `@packages/core/src/rule.ts`:
- Around line 5-9: The JSDoc comment for the RuleContext interface states that
rules only see ResolvedHead[], but the interface now also includes an optional
images field. Update the comment above the RuleContext interface definition to
accurately reflect that rules receive both a heads field and an optional images
field for Performance rules, making it clear that the interface is no longer
mode-independent in the way the current comment suggests.

In `@packages/core/test/agent-report.test.ts`:
- Line 51: The regex assertion in the test at the expect(md).toMatch() call is
too permissive and will pass even if the heading reverts to including "SEO
fixes". Instead of using the partial match regex /^# svelte-vitals/m, make the
assertion more specific by matching the exact expected heading format so that
any regression where "SEO fixes" gets added back to the heading will cause the
test to fail.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fb24a000-773d-401a-ad8d-91ec546f5767

📥 Commits

Reviewing files that changed from the base of the PR and between 1028d9b and 64d8023.

📒 Files selected for processing (36)
  • .changeset/performance-v0.4.md
  • README.md
  • docs/superpowers/plans/2026-06-22-performance-v0.4.md
  • docs/superpowers/specs/2026-06-22-performance-v0.4-design.md
  • packages/cli/src/index.ts
  • packages/cli/src/providers/source/parse.ts
  • packages/cli/src/providers/source/routes.ts
  • packages/cli/test/fixtures/basic-project/src/routes/img/+page.svelte
  • packages/cli/test/parse-file.test.ts
  • packages/cli/test/run.test.ts
  • packages/cli/test/source-provider.test.ts
  • packages/core/src/images.ts
  • packages/core/src/index.ts
  • packages/core/src/reporter/agent.ts
  • packages/core/src/reporter/console.ts
  • packages/core/src/reporter/github.ts
  • packages/core/src/reporter/json.ts
  • packages/core/src/reporter/sarif.ts
  • packages/core/src/rule.ts
  • packages/core/src/rules/index.ts
  • packages/core/src/rules/perf/image-rule.ts
  • packages/core/src/rules/perf/images.ts
  • packages/core/src/rules/seo/head-tag-rule.ts
  • packages/core/src/rules/seo/project-rules.ts
  • packages/core/src/rules/seo/seo001-title.ts
  • packages/core/src/scoring/score.ts
  • packages/core/src/types.ts
  • packages/core/test/agent-report.test.ts
  • packages/core/test/console-report.test.ts
  • packages/core/test/github-report.test.ts
  • packages/core/test/json-report.test.ts
  • packages/core/test/perf-rules.test.ts
  • packages/core/test/rule-category.test.ts
  • packages/core/test/sarif-report.test.ts
  • packages/core/test/score.test.ts
  • packages/vite/test/analyze.test.ts

Comment thread packages/core/src/reporter/sarif.ts
Comment thread packages/core/src/rules/perf/image-rule.ts
…rint (#10)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds the first non-SEO Vitals category (Performance v0.4) to @svelte-vitals/core and wires up a reusable multi-category foundation (category-tagged results, per-category scoring, and category-aware reporters). This extends static-mode analysis to produce per-<img> findings with file + line locations while keeping existing SEO scoring/output behavior backward compatible (top-level JSON score remains SEO-only).

Changes:

  • Introduces PERF001 (missing <img> width/height) and PERF002 (missing loading) plus a shared imageRule factory and image IR (ImageInfo/ResolvedImages).
  • Adds multi-category plumbing: Result.category/Result.line, scoresByCategory, and category-aware console/json/agent/github/sarif reporting.
  • Extends the CLI static provider to collect <img> facts across each route’s layout chain and feed them into RuleContext.images.

Reviewed changes

Copilot reviewed 36 out of 36 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
README.md Roadmap/docs updated to reflect Performance v0.4 shipping and upcoming categories.
packages/vite/test/analyze.test.ts Updates plugin-mode console header expectation after reporter header changes.
packages/core/test/score.test.ts Adds coverage for scoresByCategory behavior and SEO defaulting.
packages/core/test/sarif-report.test.ts Verifies SARIF startLine and fingerprint disambiguation using Result.line.
packages/core/test/rule-category.test.ts Ensures rule results carry category info (SEO rules emit seo).
packages/core/test/perf-rules.test.ts Adds unit tests for PERF001/PERF002 and line/file behavior.
packages/core/test/json-report.test.ts Asserts JSON includes categories and per-issue category/line.
packages/core/test/github-report.test.ts Asserts GitHub annotations include line when available.
packages/core/test/console-report.test.ts Asserts console includes Performance score section and file:line output.
packages/core/test/agent-report.test.ts Updates agent heading and verifies perf findings are included.
packages/core/src/types.ts Extends Result with category? and line?; defines Category union.
packages/core/src/scoring/score.ts Adds scoresByCategory helper to reuse computeScore per category.
packages/core/src/rules/seo/seo001-title.ts Tags SEO001 results with category: 'seo'.
packages/core/src/rules/seo/project-rules.ts Tags project SEO rules with category: 'seo'.
packages/core/src/rules/seo/head-tag-rule.ts Tags head-tag-rule-produced results with category: 'seo'.
packages/core/src/rules/perf/images.ts Defines PERF001/PERF002 rule configurations using imageRule.
packages/core/src/rules/perf/image-rule.ts Adds imageRule factory emitting per-image findings with optional line.
packages/core/src/rules/index.ts Registers/re-exports Performance rules alongside existing SEO rules.
packages/core/src/rule.ts Extends RuleContext with optional images?: ResolvedImages[].
packages/core/src/reporter/sarif.ts Uses Result.line for SARIF region startLine + fingerprints.
packages/core/src/reporter/json.ts Adds categories map; tags issues with category and optional line.
packages/core/src/reporter/github.ts Adds line=... to workflow-command annotations when present.
packages/core/src/reporter/console.ts Prints per-category score lines and appends :line to locations.
packages/core/src/reporter/agent.ts Makes the agent heading category-neutral (“fixes”).
packages/core/src/index.ts Re-exports new image/perf/scoring APIs.
packages/core/src/images.ts Introduces mode-independent image IR types.
packages/cli/test/source-provider.test.ts Adds coverage for layout+page image collection per route.
packages/cli/test/run.test.ts Adds e2e assertion that PERF001 surfaces in JSON output.
packages/cli/test/parse-file.test.ts Adds parsing tests for <img> attribute presence + line collection.
packages/cli/test/fixtures/basic-project/src/routes/img/+page.svelte Adds a fixture route containing an <img> missing dimensions.
packages/cli/src/providers/source/routes.ts Adds sourceImageProvider to collect per-route images via layout chain.
packages/cli/src/providers/source/parse.ts Adds <img> collection + line extraction to the static parser.
packages/cli/src/index.ts Wires collected images into runRules via RuleContext.images.
docs/superpowers/specs/2026-06-22-performance-v0.4-design.md Design spec documenting v0.4 scope and architecture.
docs/superpowers/plans/2026-06-22-performance-v0.4.md Implementation plan/checklist for the work.
.changeset/performance-v0.4.md Changeset for publishing core + cli minors for Performance v0.4.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/cli/src/providers/source/parse.ts
oekazuma and others added 3 commits June 22, 2026 18:30
…itives (#10)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ing (#10)

Address code-review findings on the Performance v0.4 branch:

- Collect heads and images in one walk of each route's layout chain
  (collectRoutes), so every .svelte file is read and parsed once instead
  of twice. analyzeProject now collects in a single call.
- PERF rules emit nothing for routes with no <img>, so a zero-image
  project hides the Performance category instead of reporting 100/100,
  and the console "Passed" section is no longer padded with per-route
  PERF passes for image-less routes.
- Tidy the console header (Svelte Vitals  ·  <mode>) and drop the unused
  _config param (subsumed by the single-pass refactor).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rop dead provider (#10)

- console: render per-category score lines from the already-computed
  scoresByCategory result instead of recomputing computeScore per category
- perf: passing seed result no longer carries a fix (nothing to remediate);
  add a regression assertion
- cli: remove the unused, untyped sourceImageProvider (collectRoutes is the
  single collection seam); point its test at collectRoutes
- docs: note non-<img> image sources (enhanced:img, picture, svelte:element,
  component images) as out of scope for v0.4

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants