Skip to content

chore(docs): rewrite CLAUDE.md, archive outdated docs, update README - #729

Merged
dcoutinho1328 merged 11 commits into
developmentfrom
chore/docs/update-documentation
Apr 15, 2026
Merged

chore(docs): rewrite CLAUDE.md, archive outdated docs, update README#729
dcoutinho1328 merged 11 commits into
developmentfrom
chore/docs/update-documentation

Conversation

@dcoutinho1328

@dcoutinho1328 dcoutinho1328 commented Apr 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Rewrote CLAUDE.md to reflect current ports & adapters architecture, Zustand store patterns, layer rules, and compilation pipeline
  • Archived all docs/ documentation to docs/outdated/ (no longer actively maintained)
  • Deleted completed migration documentation (migration-state.md, migration-tracker.md, ports/WIRING.md)
  • Updated README.md Node.js version constraint (removed x64 restriction, added <24 upper bound)

Test plan

  • Verify CLAUDE.md accurately reflects current codebase architecture
  • Confirm no referenced documentation was still actively needed

Summary by CodeRabbit

  • Documentation

    • Large rewrite of development guidance with a repository-specific architecture, ports & adapters, IPC/bridge conventions, store/component organization, navigation/editor/compiler flows, testing/style guidance, and contribution patterns; removed obsolete migration-tracking and platform-wiring docs.
  • Chores

    • Tightened Node.js requirement to >=20 <24.
    • Refined CI cross-repo sync workflow and added gated jobs for dependency/script/tooling checks.
  • Tools

    • Added new executable comparison utilities to validate shared dependencies, surface definitions, and tooling/config parity across repos.

Migration documentation deleted (completed work). Remaining docs
moved to docs/outdated/. CLAUDE.md rewritten to reflect current
ports & adapters architecture, Zustand store patterns, layer rules,
and compilation pipeline. README Node.js version constraint updated.

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

coderabbitai Bot commented Apr 15, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@dcoutinho1328 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 44 minutes and 4 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 44 minutes and 4 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 436f2805-cf07-4f6f-b671-4f69bf1b43c9

📥 Commits

Reviewing files that changed from the base of the PR and between dbb9abe and 63234f2.

📒 Files selected for processing (2)
  • .github/workflows/ci-sync.yml
  • tsconfig.json

Walkthrough

Expanded and replaced repository guidance in CLAUDE.md, tightened Node.js range in README.md, removed three migration/wiring docs, added CI cross-repo sync filtering and three compare scripts, and introduced tooling for conditional cross-repo checks.

Changes

Cohort / File(s) Summary
Core documentation
CLAUDE.md
Rewrote generic guidance into an OpenPLC Editor–specific architecture doc: layered layout (src/main, src/frontend, src/backend, src/middleware, types, __architecture__), Ports & Adapters, PlatformProvider wiring model, typed IPC bridge locations, Zustand store conventions (19 slices), Atomic-style components, navigation/editor flow, compilation/debug pipeline, testing/coverage rules, tooling and environment notes, and “Important Patterns.”
Repository README
README.md
Constrained Node.js requirement to >=20 <24 and removed explicit x64 qualifier.
Removed migration docs
docs/migration-state.md, docs/migration-tracker.md, docs/ports/WIRING.md
Deleted migration progress, migration-tracker mapping, and platform wiring guide documentation files.
CI workflow
.github/workflows/ci-sync.yml
Renamed workflow and removed PR-paths trigger; added path-filter step (dorny/paths-filter) to detect shared-surface changes and gate the existing surface-sync job plus three new jobs (deps-sync, script-sync, tooling-sync). Each job conditionally checks out openplc-web only when its filter output is true (jobs set continue-on-error: true and fall back to main). Final report step now skips when no shared changes detected.
Cross-repo comparison scripts
scripts/compare-dependencies.py, scripts/compare-surface-definitions.py, scripts/compare-tooling.py
Added three executable Python scripts: dependency version equality checker (compare-dependencies.py), SURFACES constant extractor/comparator for scripts/compare-surfaces.py (compare-surface-definitions.py), and tooling/config comparator (file SHA checks, ESLint equivalence, TS compilerOptions subset) (compare-tooling.py). Each exposes main() -> int and CLI entrypoint.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant PR as "PR (editor repo)"
  participant GH as "GitHub Actions (ci-sync)"
  participant Filter as "paths-filter step"
  participant Surface as "surface-sync job"
  participant Deps as "deps-sync job"
  participant Script as "script-sync job"
  participant Tooling as "tooling-sync job"
  participant Web as "openplc-web checkout & compare scripts"

  PR->>GH: PR triggers workflow
  GH->>Filter: run path detection on editor tree
  Filter-->>GH: outputs (shared, deps, script, tooling) flags
  GH->>Surface: run only if shared == 'true'
  Surface->>Web: conditional checkout (shared == 'true')
  Surface->>Web: run compare-surface logic
  GH->>Deps: run only if deps == 'true' and CROSS_REPO_TOKEN
  Deps->>Web: conditional checkout (deps == 'true')
  Deps->>Web: run scripts/compare-dependencies.py
  GH->>Script: run only if script == 'true' and CROSS_REPO_TOKEN
  Script->>Web: conditional checkout (script == 'true')
  Script->>Web: run scripts/compare-surface-definitions.py
  GH->>Tooling: run only if tooling == 'true' and CROSS_REPO_TOKEN
  Tooling->>Web: conditional checkout (tooling == 'true')
  Tooling->>Web: run scripts/compare-tooling.py
  Note right of GH: Final report step runs only when shared == 'true'
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

enhancement

Suggested reviewers

  • vmleroy
  • JoaoGSP
  • thiagoralves

Poem

🐰 I hopped through files, nibbling lines,

Rewrote the map where wiring shines.
CI now watches paths with care,
Scripts compare what lives out there.
Hop, build, and sync — a tidy pair!

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description lacks most required template sections including References, DOD checklist, test coverage, and integration/e2e test status. Complete the pull request description by adding References section, full DOD checklist with checkboxes marked appropriately, test coverage percentage, and outcomes of integration/e2e tests.
Docstring Coverage ⚠️ Warning Docstring coverage is 27.27% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: rewriting CLAUDE.md, archiving outdated docs, and updating README.

✏️ 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 chore/docs/update-documentation

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
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@CLAUDE.md`:
- Line 37: In CLAUDE.md update the unlabeled fenced code blocks (the
triple-backtick blocks beginning at the positions referenced) to include
explicit language identifiers (e.g., ```text, ```bash, or ```typescript) so
markdownlint MD040 warnings are resolved; locate the backtick fences shown in
the diff and change their opening fences to include the appropriate language
token for each block (for example replace ``` with ```text for the src/ and
assets blocks, and similarly add a suitable language for the
src/frontend/components/ and PLCProjectData flow block).
- Around line 42-43: The CLAUDE.md store summary is incorrect: it says “19
slices” and lists slice names (e.g., clipboard) that don't match the actual
RootState in src/frontend/store/index.ts (the RootState composed of 17 slices).
Update the documentation to reflect the current store contract by opening
RootState (identify the slice exports and keys in the store's combine/configure
call in index.ts) and change the count from 19 to 17 and mirror the exact slice
keys/names shown in RootState (remove or rename entries like clipboard if they
no longer exist); ensure lines previously referencing slice details (around the
section that lists slices) match the current slice names and ordering.
- Around line 50-51: The docs currently point the compilation orchestration to
the wrong location; update the documentation lines that reference the
editor/compiler path to instead reference the CompilerModule implemented in the
main modules compiler directory (the module named CompilerModule that implements
the IEC 61131-3 pipeline). Replace the incorrect module path/string in the
README/docs with one that clearly identifies CompilerModule in the main/modules
compiler area so contributors are directed to the actual implementation.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e1082d70-60c6-4355-91f2-2dcdcebe2b04

📥 Commits

Reviewing files that changed from the base of the PR and between b40774a and 1894296.

📒 Files selected for processing (19)
  • CLAUDE.md
  • README.md
  • docs/migration-state.md
  • docs/migration-tracker.md
  • docs/outdated/ARDUINO_UNO_Q_BINARY_SIZE_FIX.md
  • docs/outdated/HEADLESS_SETUP.md
  • docs/outdated/dead-code-inventory.md
  • docs/outdated/debugger-opcua-shared-utilities.md
  • docs/outdated/external-binaries-strategy.md
  • docs/outdated/name-type-linking-design.md
  • docs/outdated/opcua-server-configuration/01-design-overview.md
  • docs/outdated/opcua-server-configuration/02-ui-screen-specifications.md
  • docs/outdated/opcua-server-configuration/03-json-configuration-mapping.md
  • docs/outdated/opcua-server-configuration/04-implementation-phases.md
  • docs/outdated/opcua-server-configuration/README.md
  • docs/outdated/s7comm-server-implementation.md
  • docs/outdated/unified-frontend-serialization.md
  • docs/outdated/variable-id-audit.md
  • docs/ports/WIRING.md
💤 Files with no reviewable changes (3)
  • docs/migration-state.md
  • docs/migration-tracker.md
  • docs/ports/WIRING.md

Comment thread CLAUDE.md
Comment thread CLAUDE.md
Comment thread CLAUDE.md
Remove paths filter from ci-sync workflow trigger so the required
check always runs and reports a status. Uses dorny/paths-filter
inside the job to skip the expensive comparison when no shared
surface files changed.

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

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
.github/workflows/ci-sync.yml (1)

15-25: Consider moving checkout after the filter to skip unnecessary clone time on docs-only PRs.

Line 15 currently checks out editor before determining whether shared surfaces changed. The dorny/paths-filter@v3 action uses GitHub's REST API for pull request events and does not require the repository to be checked out—you can safely run the filter first, then checkout only when shared == 'true'. This saves clone time for PRs that modify only documentation or non-shared code.

Suggested refactor
-      - name: Checkout editor repo
-        uses: actions/checkout@v4
-        with:
-          path: editor
-
       - name: Check for shared surface changes
         uses: dorny/paths-filter@v3
         id: filter
         with:
-          working-directory: editor
           filters: |
             shared:
               - 'src/frontend/**'
               - 'src/middleware/shared/**'
               - 'src/backend/shared/**'
               - 'src/__architecture__/**'
               - 'scripts/compare-surfaces.py'
               - '.github/workflows/ci-sync.yml'
+
+      - name: Checkout editor repo
+        if: steps.filter.outputs.shared == 'true'
+        uses: actions/checkout@v4
+        with:
+          path: editor
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci-sync.yml around lines 15 - 25, Move the "Checkout
editor repo" step to after the "Check for shared surface changes" step and run
the dorny/paths-filter@v3 step (id: filter) before any checkout; the
paths-filter action does not require the repo to be checked out, so keep the
existing working-directory and filters on the filter step and conditionally
execute the actions/checkout@v4 "Checkout editor repo" step only when the filter
output indicates shared == 'true' (use the filter step outputs in the checkout
step's if condition). Ensure the step names/ids ("Checkout editor repo", "Check
for shared surface changes", id: filter) and the filters input remain unchanged
except for relocating the checkout and adding the conditional.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.github/workflows/ci-sync.yml:
- Around line 15-25: Move the "Checkout editor repo" step to after the "Check
for shared surface changes" step and run the dorny/paths-filter@v3 step (id:
filter) before any checkout; the paths-filter action does not require the repo
to be checked out, so keep the existing working-directory and filters on the
filter step and conditionally execute the actions/checkout@v4 "Checkout editor
repo" step only when the filter output indicates shared == 'true' (use the
filter step outputs in the checkout step's if condition). Ensure the step
names/ids ("Checkout editor repo", "Check for shared surface changes", id:
filter) and the filters input remain unchanged except for relocating the
checkout and adding the conditional.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c08b7886-9f61-4bf5-a4f1-161d6941ace4

📥 Commits

Reviewing files that changed from the base of the PR and between 1894296 and 7be88a6.

📒 Files selected for processing (1)
  • .github/workflows/ci-sync.yml

dcoutinho1328 and others added 7 commits April 15, 2026 12:34
dorny/paths-filter uses the GitHub API for PR file detection,
not local git. The working-directory param is unnecessary.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The paths filter causes the sync check to not report a status on PRs
that don't touch shared surfaces, breaking required status checks.
Replace with a gh api call that detects shared surface changes at
runtime and exits early with success when none are found.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
gh api fails with 'Resource not accessible by integration' in the
same way dorny/paths-filter did. Replace with a local git diff
against the base branch after checkout.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Split the sync workflow into three independent jobs that all run on
every PR but early-exit when their respective files are unchanged:
- surface-sync: shared UI surface files (existing)
- deps-sync: shared production dependency versions in package.json
- script-sync: SURFACES definition parity in compare-surfaces.py

Also switch path detection from gh api to local git diff to avoid
'Resource not accessible by integration' errors, and remove
self-referential paths (ci-sync.yml, compare-surfaces.py) from the
surface-sync filter since they are not shared surfaces.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move the embedded Python from deps-sync and script-sync workflow jobs
into dedicated scripts under scripts/:
- compare-dependencies.py: shared production dependency version check
- compare-surface-definitions.py: SURFACES list parity check

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New job checks that lint, formatter, and TypeScript configurations
produce equivalent output on shared surfaces:
- .prettierrc and scripts/* must be byte-identical
- ESLint rules/plugins must match (ignores can differ per-repo)
- TypeScript key compiler options (strict, jsx, paths, etc.) must match

Runs on every PR, early-exits when no config/script files changed.

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

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (5)
scripts/compare-tooling.py (2)

207-210: Consider explicit encoding for file reads.

The open() calls here (and elsewhere in the script) rely on the platform default encoding. For consistency and to avoid potential issues on non-UTF-8 systems, consider specifying encoding="utf-8".

♻️ Proposed fix
-    with open(web_file) as f:
+    with open(web_file, encoding="utf-8") as f:
         web_config = parse_jsonc(f.read())
-    with open(editor_file) as f:
+    with open(editor_file, encoding="utf-8") as f:
         editor_config = parse_jsonc(f.read())
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/compare-tooling.py` around lines 207 - 210, The file reads use
open(web_file) and open(editor_file) without an explicit encoding; update both
calls (and other open(...) usages in this script) to specify encoding="utf-8" so
parse_jsonc receives UTF-8 text consistently—modify the open calls that produce
web_config and editor_config (and any similar file reads) to open(...,
encoding="utf-8").

70-77: Regex may not handle complex ignores arrays.

The pattern \{\s*ignores:\s*\[.*?\],?\s*\} uses non-greedy matching which won't correctly handle nested structures within the ignores array (e.g., arrays of arrays or objects). For typical ESLint ignore patterns (simple string arrays), this should work fine.

If you expect more complex configurations in the future, consider a proper JS parser or more robust stripping logic.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/compare-tooling.py` around lines 70 - 77, The current
strip_eslint_ignores function uses a non-greedy regex that can break on nested
brackets/objects inside the ignores array; replace the regex approach with a
small parser: in strip_eslint_ignores locate the "{", the "ignores" key and its
following "[" then scan forward counting nested brackets/braces/strings to find
the correct matching "]" and the closing "}" and remove that entire block;
alternatively call out to a JS/JSON parser if the config is valid JS/JSON. Keep
function name strip_eslint_ignores and ensure it returns the cleaned text.
scripts/compare-surface-definitions.py (1)

20-28: Missing error handling for file operations and AST parsing.

The function can raise unhandled exceptions:

  1. FileNotFoundError if the target file doesn't exist
  2. SyntaxError from ast.parse() if the file has invalid Python syntax
  3. ValueError/SyntaxError from ast.literal_eval() if SURFACES contains non-literal values

Consider wrapping in try-except and returning None (or a more descriptive error) on failure, similar to how main() already handles None returns.

♻️ Proposed error handling
 def extract_surfaces(filepath: Path) -> list[str] | None:
+    try:
-    with open(filepath) as f:
+    with open(filepath, encoding="utf-8") as f:
         tree = ast.parse(f.read())
+    except (FileNotFoundError, SyntaxError) as e:
+        print(f"::warning::Could not parse {filepath}: {e}")
+        return None
     for node in ast.walk(tree):
         if isinstance(node, ast.Assign):
             for target in node.targets:
                 if isinstance(target, ast.Name) and target.id == "SURFACES":
-                    return sorted(ast.literal_eval(node.value))
+                    try:
+                        return sorted(ast.literal_eval(node.value))
+                    except (ValueError, SyntaxError):
+                        return None
     return None
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/compare-surface-definitions.py` around lines 20 - 28, The
extract_surfaces function lacks error handling for file I/O and AST operations;
wrap the file read, ast.parse, and ast.literal_eval calls inside a try/except
that catches FileNotFoundError, SyntaxError, ValueError (and TypeError) and
return None on failure (or optionally log the exception), ensuring
extract_surfaces consistently returns None on error like main expects; keep the
search for the SURFACES assignment and the sorted return intact but move those
operations inside the try block so any parsing/evaluation errors are handled
gracefully.
scripts/compare-dependencies.py (1)

34-37: Missing error handling for file operations.

If package.json is missing or contains invalid JSON, the script will crash with an unhandled exception. Consider adding try-except with informative error messages consistent with the other comparison scripts.

♻️ Proposed error handling
+    try:
-    with open(args.web_root / "package.json") as f:
+    with open(args.web_root / "package.json", encoding="utf-8") as f:
         web_deps = json.load(f).get("dependencies", {})
+    except (FileNotFoundError, json.JSONDecodeError) as e:
+        print(f"::error::Could not read web package.json: {e}")
+        return 1
+
+    try:
-    with open(args.editor_root / "package.json") as f:
+    with open(args.editor_root / "package.json", encoding="utf-8") as f:
         editor_deps = json.load(f).get("dependencies", {})
+    except (FileNotFoundError, json.JSONDecodeError) as e:
+        print(f"::error::Could not read editor package.json: {e}")
+        return 1
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/compare-dependencies.py` around lines 34 - 37, Wrap the package.json
reads in a try/except that catches FileNotFoundError and json.JSONDecodeError
when opening args.web_root / "package.json" and args.editor_root /
"package.json" (the code that produces web_deps and editor_deps); on error, emit
an informative message consistent with other comparison scripts (include which
path failed and the exception message) and exit with a non‑zero status (or
fallback to empty {} if that matches existing behavior). Ensure you update both
the web_deps and editor_deps loading blocks and use the same logging/exit
pattern used elsewhere in the repository.
.github/workflows/ci-sync.yml (1)

348-360: Tooling filter may be overly broad for scripts/.

The regex ^(\.prettierrc$|eslint\.config\.|tsconfig|scripts/) matches any file under scripts/, which will trigger tooling-sync even for unrelated script changes (e.g., if you add a build script later).

Consider narrowing to specific tooling-related scripts:

♻️ Suggested more precise filter
-          if echo "$CHANGED" | grep -qE '^(\.prettierrc$|eslint\.config\.|tsconfig|scripts/)'; then
+          if echo "$CHANGED" | grep -qE '^(\.prettierrc$|eslint\.config\.|tsconfig|scripts/compare-)'; then

This would only match comparison scripts (compare-*.py) rather than all scripts.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci-sync.yml around lines 348 - 360, The tooling-change
filter in the "Check for tooling changes" step (id: filter) is too broad because
the regex ^(\.prettierrc$|eslint\.config\.|tsconfig|scripts/) matches any file
under scripts/ and will trigger tooling-sync for unrelated script edits; update
the git-diff check (the CHANGED determination) to narrow the scripts pattern to
only tooling-related files (e.g., replace the scripts/ alternative with a
specific glob like scripts/compare-*.py or explicit filenames used for tooling)
so that only intended tooling script changes cause changed=true while keeping
the existing checks for .prettierrc, eslint.config.*, and tsconfig.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/compare-tooling.py`:
- Around line 85-114: The parse_jsonc function uses text.index(...) for skipping
comments which raises ValueError on missing delimiters; replace those index
calls with text.find(...) and handle -1 results: for the single-line comment
case in parse_jsonc (where it currently does i = text.index('\n', i) if '\n' in
text[i:] else len(text)), use end = text.find('\n', i) and set i = len(text) if
end == -1; for the block comment case (end = text.index('*/', i)) use end =
text.find('*/', i) and either set i = len(text) to treat the rest as a comment
or raise a clear ValueError/ParseError like "Unterminated block comment in
parse_jsonc" so malformed input doesn't crash with a raw ValueError; update the
code paths inside parse_jsonc accordingly.

---

Nitpick comments:
In @.github/workflows/ci-sync.yml:
- Around line 348-360: The tooling-change filter in the "Check for tooling
changes" step (id: filter) is too broad because the regex
^(\.prettierrc$|eslint\.config\.|tsconfig|scripts/) matches any file under
scripts/ and will trigger tooling-sync for unrelated script edits; update the
git-diff check (the CHANGED determination) to narrow the scripts pattern to only
tooling-related files (e.g., replace the scripts/ alternative with a specific
glob like scripts/compare-*.py or explicit filenames used for tooling) so that
only intended tooling script changes cause changed=true while keeping the
existing checks for .prettierrc, eslint.config.*, and tsconfig.

In `@scripts/compare-dependencies.py`:
- Around line 34-37: Wrap the package.json reads in a try/except that catches
FileNotFoundError and json.JSONDecodeError when opening args.web_root /
"package.json" and args.editor_root / "package.json" (the code that produces
web_deps and editor_deps); on error, emit an informative message consistent with
other comparison scripts (include which path failed and the exception message)
and exit with a non‑zero status (or fallback to empty {} if that matches
existing behavior). Ensure you update both the web_deps and editor_deps loading
blocks and use the same logging/exit pattern used elsewhere in the repository.

In `@scripts/compare-surface-definitions.py`:
- Around line 20-28: The extract_surfaces function lacks error handling for file
I/O and AST operations; wrap the file read, ast.parse, and ast.literal_eval
calls inside a try/except that catches FileNotFoundError, SyntaxError,
ValueError (and TypeError) and return None on failure (or optionally log the
exception), ensuring extract_surfaces consistently returns None on error like
main expects; keep the search for the SURFACES assignment and the sorted return
intact but move those operations inside the try block so any parsing/evaluation
errors are handled gracefully.

In `@scripts/compare-tooling.py`:
- Around line 207-210: The file reads use open(web_file) and open(editor_file)
without an explicit encoding; update both calls (and other open(...) usages in
this script) to specify encoding="utf-8" so parse_jsonc receives UTF-8 text
consistently—modify the open calls that produce web_config and editor_config
(and any similar file reads) to open(..., encoding="utf-8").
- Around line 70-77: The current strip_eslint_ignores function uses a non-greedy
regex that can break on nested brackets/objects inside the ignores array;
replace the regex approach with a small parser: in strip_eslint_ignores locate
the "{", the "ignores" key and its following "[" then scan forward counting
nested brackets/braces/strings to find the correct matching "]" and the closing
"}" and remove that entire block; alternatively call out to a JS/JSON parser if
the config is valid JS/JSON. Keep function name strip_eslint_ignores and ensure
it returns the cleaned text.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 440ae5b3-f4de-469d-a3ba-f24351912c89

📥 Commits

Reviewing files that changed from the base of the PR and between 7be88a6 and dbb9abe.

📒 Files selected for processing (4)
  • .github/workflows/ci-sync.yml
  • scripts/compare-dependencies.py
  • scripts/compare-surface-definitions.py
  • scripts/compare-tooling.py

Comment on lines +85 to +114
def parse_jsonc(text: str) -> dict:
"""Parse JSON with comments (// and /* */) and trailing commas."""
# Strip comments while preserving strings containing //
result = []
i = 0
while i < len(text):
if text[i] == '"':
j = i + 1
while j < len(text):
if text[j] == '\\':
j += 2
continue
if text[j] == '"':
j += 1
break
j += 1
result.append(text[i:j])
i = j
elif text[i:i+2] == '//':
i = text.index('\n', i) if '\n' in text[i:] else len(text)
elif text[i:i+2] == '/*':
end = text.index('*/', i)
i = end + 2
else:
result.append(text[i])
i += 1
text = "".join(result)
# Strip trailing commas before } or ]
text = re.sub(r",\s*([}\]])", r"\1", text)
return json.loads(text)

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.

⚠️ Potential issue | 🟡 Minor

parse_jsonc can raise ValueError on malformed input.

The text.index() calls on lines 104 and 106 raise ValueError if the substring is not found:

  • Line 104: Single-line comment (//) at EOF without trailing newline
  • Line 106: Unclosed block comment (/* without */)

While valid JSONC files won't have these issues, a corrupted or truncated file could crash the script.

🛡️ Proposed defensive fix
         elif text[i:i+2] == '//':
-            i = text.index('\n', i) if '\n' in text[i:] else len(text)
+            newline_pos = text.find('\n', i)
+            i = newline_pos if newline_pos != -1 else len(text)
         elif text[i:i+2] == '/*':
-            end = text.index('*/', i)
+            end = text.find('*/', i)
+            if end == -1:
+                # Unclosed block comment - skip to end
+                i = len(text)
+                continue
             i = end + 2
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/compare-tooling.py` around lines 85 - 114, The parse_jsonc function
uses text.index(...) for skipping comments which raises ValueError on missing
delimiters; replace those index calls with text.find(...) and handle -1 results:
for the single-line comment case in parse_jsonc (where it currently does i =
text.index('\n', i) if '\n' in text[i:] else len(text)), use end =
text.find('\n', i) and set i = len(text) if end == -1; for the block comment
case (end = text.index('*/', i)) use end = text.find('*/', i) and either set i =
len(text) to treat the rest as a comment or raise a clear ValueError/ParseError
like "Unterminated block comment in parse_jsonc" so malformed input doesn't
crash with a raw ValueError; update the code paths inside parse_jsonc
accordingly.

dcoutinho1328 and others added 2 commits April 15, 2026 14:36
Add noFallthroughCasesInSwitch, noUnusedLocals, and
noUnusedParameters to match web's tsconfig.app.json so both repos
type-check shared surfaces with the same compiler options.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The deps-sync, script-sync, and tooling-sync jobs were checking out
the companion repo at the base branch, causing failures when both
repos have coordinated changes on matching feature branches. Now tries
head branch -> base branch -> main, so cross-repo feature branches
are compared against each other.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@dcoutinho1328
dcoutinho1328 merged commit 28d322f into development Apr 15, 2026
14 checks passed
@dcoutinho1328
dcoutinho1328 deleted the chore/docs/update-documentation branch April 15, 2026 18:43
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.

1 participant