Skip to content

Rename diff-viewer package to webviews and pin TanStack Router - #5426

Closed
lawrencecchen wants to merge 2 commits into
mainfrom
feat-diff-viewer-tanstack-router
Closed

lawrencecchen wants to merge 2 commits into
mainfrom
feat-diff-viewer-tanstack-router

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Jun 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • rename the React app source directory from diff-viewer to webviews
  • rename generated app assets from Resources/markdown-viewer/diff-viewer-app to Resources/markdown-viewer/webviews-app
  • update CI/scripts and Swift asset lookup to use the webviews bundle name
  • add exact-pinned @tanstack/react-router 1.170.11 with a build-time security verifier for the TanStack lockfile entries

Verification

  • ./scripts/build-webviews-app.sh
  • ./scripts/build-webviews-app.sh --check
  • ./scripts/check-webviews-react-compiler.mjs
  • bun run test (webviews)
  • bun run lint (webviews)

Security references:


Note

Medium Risk
Bundled asset path renames must stay aligned with Swift copy logic or the in-app diff viewer can fail to load; the new dependency adds supply-chain surface area mitigated by exact pins and integrity checks.

Overview
Rebrands the embedded React bundle from diff-viewer to webviews so the same package can host multiple in-app webviews (the diff UI remains the first consumer).

Naming and packaging: @cmux/diff-viewer becomes @cmux/webviews; source lives under webviews/; Vite output and committed assets move to Resources/markdown-viewer/webviews-app with env CMUX_WEBVIEWS_OUT_DIR. CI’s react-apps-check job and scripts build-webviews-app.sh / check-webviews-react-compiler.mjs replace the diff-viewer equivalents.

macOS integration: Swift copies bundled app assets from webviews-app and exposes them as cmux-webviews-app when preparing the diff viewer runtime.

TanStack Router: Adds exact-pinned @tanstack/react-router@1.170.11 and runs verify-tanstack-router-security.mjs before build to enforce lockfile versions/integrity and block known compromised releases (GHSA-g7cv-rxg3-hmpx).

Reviewed by Cursor Bugbot for commit e5b4a25. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • Documentation

    • Updated webviews documentation and build instructions to reflect the rebranded webviews bundle.
  • Chores

    • Consolidated build infrastructure and assets under the unified webviews module.
    • Updated CI and build workflows to target the webviews bundle.
  • Dependencies

    • Added TanStack Router and introduced an automated verification step to enforce its pinned version.
  • Tests

    • Adjusted vendored test expectations to the new webviews layout.

@vercel

vercel Bot commented Jun 5, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Jun 6, 2026 3:57am
cmux-staging Building Building Preview, Comment Jun 6, 2026 3:57am

@coderabbitai

coderabbitai Bot commented Jun 5, 2026 •

Copy link
Copy Markdown

Complex PR? Review this PR in Change Stack to move by importance, not file order.

Review Change Stack

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 560e1135-223e-4962-9251-8f22ddada793

📥 Commits

Reviewing files that changed from the base of the PR and between b202f5b and e5b4a25.

📒 Files selected for processing (2)
  • .github/workflows/ci.yml
  • CLI/cmux_open.swift

📝 Walkthrough

Walkthrough

This PR refactors the diff-viewer package to webviews across build infrastructure, CI, and asset paths, while integrating @tanstack/react-router with a new security verification script that validates package pinning and lockfile integrity at build time.

Changes

Webviews Rename and TanStack Router Integration

Layer / File(s) Summary
Package identity and documentation
webviews/package.json, webviews/README.md
Renames the package from @cmux/diff-viewer to @cmux/webviews, adds @tanstack/react-router@1.170.11 to dependencies, updates the build script to run verify:tanstack-router verification before typecheck and vite build, and updates README to describe the webviews project scope and corresponding build/check commands.
TanStack Router security verification
webviews/scripts/verify-tanstack-router-security.mjs
Implements new security verification script that validates @tanstack/react-router is pinned to the expected version, parses lockfile entries for version and sha512 integrity, rejects any compromised versions from a hardcoded blocklist, and fails the build if validation fails.
Build system and CI retargeting
.github/workflows/ci.yml, scripts/build-webviews-app.sh, webviews/vite.config.mjs
Updates CI workflow comment and steps to target the webviews workspace instead of diff-viewer, retargets build script source/output directories to webviews/webviews-app, updates error messages for asset comparison, and changes Vite's outDir to use CMUX_WEBVIEWS_OUT_DIR environment variable with fallback to Resources/markdown-viewer/webviews-app.
Asset and compiler verification paths
scripts/check-webviews-react-compiler.mjs, CLI/cmux_open.swift
Updates React compiler verification script to read from Resources/markdown-viewer/webviews-app/main.mjs instead of the diff-viewer bundle, and updates Swift asset discovery functions to look for cmux-webviews-app and webviews-app directories instead of diff-viewer equivalents.
Test path updates
webviews/test/pierre-tree-bundle.test.ts
Updates vendored Pierre tree bundle test to reference webviews/src/App.tsx instead of diff-viewer/src/App.tsx in path assertions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

A rabbit hops through diff-viewer no more,
Now webviews bloom like clover on the floor,
With TanStack routers checked for their grace,
Build scripts dance to a webviews embrace! 🐰✨

🚥 Pre-merge checks | ✅ 18 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (18 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the main changes: renaming diff-viewer to webviews and pinning TanStack Router, which aligns with the core objectives.
Description check ✅ Passed The description covers the primary changes (renaming, asset paths, TanStack Router pinning) but does not fully match the template structure (Summary and Testing sections are provided, but Demo Video and Checklist are missing or incomplete).
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.
Cmux Swift Actor Isolation ✅ Passed PR only modifies string literals and paths in cmux_open.swift; no new types, isolation annotations, shared mutable Sendable types, or UI-bound stores are introduced or worsened.
Cmux Swift Blocking Runtime ✅ Passed PR introduces only string constant changes in CLI/cmux_open.swift (renaming asset bundle paths); no blocking synchronization patterns (semaphores, locks, sleeps, etc.) were added or expanded.
Cmux No Hacky Sleeps ✅ Passed PR introduces no fixed sleeps, delays, or polling in production TypeScript/JavaScript/shell scripts. New build/check scripts use deterministic file I/O and validation without timing constructs.
Cmux Algorithmic Complexity ✅ Passed All code changes use bounded fixed-size collections (5-10 items) with O(1) operations, single-pass iterations, and no nested scans over user-scalable data. No algorithmic complexity rule violations.
Cmux Swift Concurrency ✅ Passed PR modifies only CLI/cmux_open.swift with string replacements; no legacy async patterns are introduced or expanded.
Cmux Swift @Concurrent ✅ Passed Only Swift file (CLI/cmux_open.swift) has cosmetic string updates in synchronous functions; no async/nonisolated functions, no @concurrent annotations modified.
Cmux Swift File And Package Boundaries ✅ Passed CLI/cmux_open.swift: +2/-2 string literal changes renaming asset paths. Incidental touching of glue code with single responsibility; not tracked as oversized.
Cmux Swift Logging ✅ Passed Swift file changes are only asset directory name updates from "diff-viewer-app" to "webviews-app". No logging statements are added or materially changed; existing print statements are CLI output.
Cmux User-Facing Error Privacy ✅ Passed All messages comply: product names, standard tools (diff, bun.lock), internal Swift errors, and build-time dev-only verification script allowed by rules.
Cmux Full Internationalization ✅ Passed PR is an internal refactoring renaming diff-viewer to webviews. Changes include CI workflows, build scripts, tests, and developer docs—no new user-facing strings requiring i18n updates.
Cmux Swiftui State Layout ✅ Passed No SwiftUI state changes in PR. CLI/cmux_open.swift has only asset path string updates; other changes are CI/build scripts, JavaScript/TypeScript, and docs.
Cmux Architecture Rethink ✅ Passed Swift changes are configuration-only (2 string renames in asset paths). No timing delays, locks, observers, side channels, or split lifecycle ownership introduced. Maintains existing architecture.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR modifies only asset directory paths in cmux_open.swift; no NSWindow, NSPanel, NSWindowController, SwiftUI Window/WindowGroup code was added or materially changed.
Cmux Source Artifacts ✅ Passed All 9 changed files (workflows, source code, scripts, config, docs, tests) are intentional; no artifacts, build output, caches, or broad scratch directories are added to source control.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-diff-viewer-tanstack-router

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.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 716ca8fc89

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +27 to +30
const compromisedVersions = new Map([
["@tanstack/history", new Set(["1.161.9", "1.161.12"])],
["@tanstack/react-router", new Set(["1.169.5", "1.169.8"])],
["@tanstack/router-core", new Set(["1.169.5", "1.169.8"])],

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Expand the GHSA blocklist to all affected packages

When another GHSA-g7cv-rxg3-hmpx-affected TanStack package is added to this lockfile, this guard will still pass for known-malicious versions because the blocklist only includes three packages; the advisory covers many more affected @tanstack/* packages (for example @tanstack/react-router-devtools 1.166.16/1.166.19). Since this script is now the build-time security gate for TanStack lockfile drift, leaving the rest of the affected package/version pairs out makes the verifier give a false sense of coverage for future TanStack additions.

Useful? React with 👍 / 👎.

@lawrencecchen
lawrencecchen force-pushed the feat-diff-viewer-tanstack-router branch from 716ca8f to b202f5b Compare June 5, 2026 03:01
@lawrencecchen lawrencecchen changed the title Pin TanStack Router for diff viewer Rename diff-viewer package to webviews and pin TanStack Router Jun 5, 2026

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b202f5b. Configure here.

Comment thread CLI/cmux_open.swift

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b202f5bda4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


function parseTanstackLockEntries(text) {
const entries = new Map();
const linePattern = /^\s+"(@tanstack\/[^"]+)": \["@tanstack\/[^@"]+@([^"]+)",.*"(sha512-[^"]+)"\],?$/gm;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Parse nested TanStack entries before trusting the guard

When Bun has to keep a second copy of a package for a specific dependency, this lockfile format can use prefixed keys like parent/package while the package spec inside the array still names the real package; there are already entries of that form elsewhere in webviews/bun.lock (for example bundled/nested packages). This regex only matches keys that start exactly with @tanstack/, so a future dependency that pulls a nested compromised @tanstack/history or @tanstack/router-core would not be included in lockEntries and the GHSA blocklist loop would pass even though the bad package is present. Parse the package name from the array spec (or otherwise scan all package records) so nested TanStack copies are checked too.

Useful? React with 👍 / 👎.

@greptile-apps

greptile-apps Bot commented Jun 5, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

Renames the embedded React app source and asset bundle from diff-viewer / diff-viewer-app to webviews / webviews-app, updating CI, build scripts, and the Swift asset-copy path accordingly. It also pins @tanstack/react-router to exactly 1.170.11 and adds a build-time verifier (verify-tanstack-router-security.mjs) that checks the bun.lock integrity hashes and blocks known-compromised versions tied to GHSA-g7cv-rxg3-hmpx.

  • Asset rename — CLI/cmux_open.swift updated to look for webviews-app (from diff-viewer-app) and copy it as cmux-webviews-app; CI and build scripts follow consistently. cmuxTests/CMUXOpenCommandTests.swift was not included in the PR, leaving the test helper and its downstream assertions pointing at the old diff-viewer-app / cmux-diff-viewer-app paths.
  • TanStack security verifier — runs before every vite build, checks exact version pin in package.json, validates five TanStack transitive-dep integrity hashes against expected values, and blocks three packages at the two known-compromised version sets.

Confidence Score: 4/5

The rename is internally consistent across scripts, CI, and Swift production code, but the Swift test suite was not updated to match the new asset-directory names.

The Swift production code correctly looks for webviews-app and copies assets as cmux-webviews-app, but CMUXOpenCommandTests.swift still creates mock resources under diff-viewer-app and asserts paths containing cmux-diff-viewer-app. These tests will fail as written, confirming the rename is incomplete.

cmuxTests/CMUXOpenCommandTests.swift — the test helper and multiple assertions reference the old asset-directory names and need to be updated to match the renamed paths in CLI/cmux_open.swift.

Important Files Changed

Filename Overview
CLI/cmux_open.swift Two physical paths renamed from diff-viewer-app/cmux-diff-viewer-app to webviews-app/cmux-webviews-app; matching test scaffolding in CMUXOpenCommandTests.swift was not updated, leaving multiple assertions broken
webviews/scripts/verify-tanstack-router-security.mjs Adds a build-time security verifier that pins @tanstack/react-router to 1.170.11, validates lockfile integrity hashes for all TanStack transitive deps, and blocks known-compromised versions from GHSA-g7cv-rxg3-hmpx; logic is sound for the current bun.lock format
scripts/build-webviews-app.sh Renamed from build-diff-viewer-app.sh; --check mode diffs a temp build against committed assets, non-check mode builds in place; both paths consistent with vite outDir
.github/workflows/ci.yml CI steps updated to reference new webviews working directory and build scripts; rename is complete and consistent
webviews/package.json Renamed to @cmux/webviews; adds exact-pinned @tanstack/react-router 1.170.11 with verify:tanstack-router gate before every build
webviews/vite.config.mjs outDir updated to webviews-app; CMUX_WEBVIEWS_OUT_DIR env var allows --check builds to redirect output for diffing

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[bun run build] --> B[verify:tanstack-router]
    B --> C{package.json pin == 1.170.11?}
    C -- No --> FAIL1[exit 1]
    C -- Yes --> D{bun.lock has all 5 TanStack entries with expected hashes?}
    D -- No / hash mismatch --> FAIL2[exit 1]
    D -- Yes --> E{Any @tanstack/* entry matches compromised version set?}
    E -- Yes --> FAIL3[exit 1 GHSA-g7cv-rxg3-hmpx]
    E -- No --> F[bun run typecheck]
    F --> G[vite build]
    G --> H[Resources/markdown-viewer/webviews-app/main.mjs]
    H --> I[cmux_open.swift diffViewerBundledAppAssetDirectory looks for webviews-app]
    I --> J[copies as cmux-webviews-app in viewer assets dir]
Loading

Reviews (2): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile

Comment on lines +64 to +74
function parseTanstackLockEntries(text) {
const entries = new Map();
const linePattern = /^\s+"(@tanstack\/[^"]+)": \["@tanstack\/[^@"]+@([^"]+)",.*"(sha512-[^"]+)"\],?$/gm;
for (const match of text.matchAll(linePattern)) {
entries.set(match[1], {
version: match[2],
integrity: match[3],
});
}
return entries;
}

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.

P2 Last-write-wins on duplicate package names in lockfile parser

parseTanstackLockEntries accumulates results into a Map keyed by package name (e.g. @tanstack/react-router). If bun.lock ever contains two lines with the same @tanstack/ package name — for instance via an aliased install or a future nested-workspace setup — the Map silently overwrites the first entry with the second. The compromised-version sweep on lines 55-60 then only sees the last occurrence, so a compromised version that happens to appear earlier in the file would be invisible to the check. For a security-critical verifier, collecting all matches into an array and iterating all of them (or failing fast on any duplicate key) would close this gap without changing normal-case behavior.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment thread webviews/package.json
"dependencies": {
"@pierre/diffs": "1.2.7",
"@pierre/trees": "1.0.0-beta.4",
"@tanstack/react-router": "1.170.11",

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.

P2 @tanstack/react-router is declared but not imported anywhere in source

@tanstack/react-router is listed under dependencies, but no file in webviews/src/ imports it. Is this intentional pre-emptive pinning ahead of a follow-up PR that adds router usage, or was an import accidentally left out? If it's proactive pinning only, a comment in package.json (or the PR description) clarifying this would help future maintainers understand why an apparently unused dependency is present and security-verified.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/ci.yml (1)

1-13: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add explicit least-privilege GitHub token permissions.

Line 1 starts a workflow without a permissions block, so jobs run with default token scopes. Please pin minimal permissions at workflow level (and elevate per job only where required) to avoid accidental over-privileged CI tokens.

Suggested hardening
 name: CI
+permissions:
+  contents: read
🤖 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 @.github/workflows/ci.yml around lines 1 - 13, Add a workflow-level
permissions block to the CI workflow to enforce least-privilege for GITHUB_TOKEN
(e.g., set read-only for repo contents and other minimal scopes the majority of
jobs need) and remove relying on default token scopes; then, for any job that
requires broader access, add a job-level permissions override (permissions:)
inside that job to explicitly grant only the additional scopes it needs. Update
the top-level of the "CI" workflow (the workflow root) to include the minimal
permissions and adjust specific jobs that need push/write or id-token to
explicitly elevate there.
🤖 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.

Outside diff comments:
In @.github/workflows/ci.yml:
- Around line 1-13: Add a workflow-level permissions block to the CI workflow to
enforce least-privilege for GITHUB_TOKEN (e.g., set read-only for repo contents
and other minimal scopes the majority of jobs need) and remove relying on
default token scopes; then, for any job that requires broader access, add a
job-level permissions override (permissions:) inside that job to explicitly
grant only the additional scopes it needs. Update the top-level of the "CI"
workflow (the workflow root) to include the minimal permissions and adjust
specific jobs that need push/write or id-token to explicitly elevate there.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: f14b07a7-cc2f-4ae4-b442-3ca69b56f186

📥 Commits

Reviewing files that changed from the base of the PR and between 716ca8f and b202f5b.

⛔ Files ignored due to path filters (1)
  • webviews/bun.lock is excluded by !**/*.lock
📒 Files selected for processing (36)
  • .github/workflows/ci.yml
  • CLI/cmux_open.swift
  • Resources/markdown-viewer/webviews-app/main.mjs
  • scripts/build-webviews-app.sh
  • scripts/check-webviews-react-compiler.mjs
  • webviews/README.md
  • webviews/index.html
  • webviews/package.json
  • webviews/scripts/verify-tanstack-router-security.mjs
  • webviews/src/App.tsx
  • webviews/src/actions.ts
  • webviews/src/appearance.ts
  • webviews/src/diff-stream.ts
  • webviews/src/file-tree-refresh.ts
  • webviews/src/global.d.ts
  • webviews/src/icons.tsx
  • webviews/src/labels.ts
  • webviews/src/main.tsx
  • webviews/src/pierre-options.ts
  • webviews/src/status.ts
  • webviews/src/styles.css
  • webviews/src/types.ts
  • webviews/src/worker-pool.ts
  • webviews/test/actions.test.ts
  • webviews/test/app.test.tsx
  • webviews/test/appearance.test.ts
  • webviews/test/diff-stream.test.ts
  • webviews/test/file-tree-refresh.test.ts
  • webviews/test/labels.test.ts
  • webviews/test/pierre-options.test.ts
  • webviews/test/pierre-tree-bundle.test.ts
  • webviews/test/status.test.ts
  • webviews/test/styles.test.ts
  • webviews/test/worker-pool.test.ts
  • webviews/tsconfig.json
  • webviews/vite.config.mjs

@socket-security

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: npm caniuse-lite is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: ? → npm/@vitejs/plugin-react@5.2.0 → npm/react-doctor@0.2.14 → npm/caniuse-lite@1.0.30001793

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/caniuse-lite@1.0.30001793. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm caniuse-lite is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: ? → npm/@vitejs/plugin-react@5.2.0 → npm/react-doctor@0.2.14 → npm/caniuse-lite@1.0.30001793

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/caniuse-lite@1.0.30001793. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm caniuse-lite is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: ? → npm/@vitejs/plugin-react@5.2.0 → npm/react-doctor@0.2.14 → npm/caniuse-lite@1.0.30001793

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/caniuse-lite@1.0.30001793. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm caniuse-lite is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: ? → npm/@vitejs/plugin-react@5.2.0 → npm/react-doctor@0.2.14 → npm/caniuse-lite@1.0.30001793

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/caniuse-lite@1.0.30001793. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm css-tree is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: ? → npm/jsdom@29.1.1 → npm/css-tree@3.2.1

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/css-tree@3.2.1. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm data-urls is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: ? → npm/jsdom@29.1.1 → npm/data-urls@7.0.0

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/data-urls@7.0.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm jsdom is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: webviews/package.json → npm/jsdom@29.1.1

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/jsdom@29.1.1. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm jsdom is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: webviews/package.json → npm/jsdom@29.1.1

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/jsdom@29.1.1. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm seroval is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: ? → npm/@tanstack/react-router@1.170.11 → npm/seroval@1.5.4

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/seroval@1.5.4. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e5b4a2568e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread CLI/cmux_open.swift
Comment on lines 5627 to +5629
let appDirectory = sourceDirectory
.deletingLastPathComponent()
.appendingPathComponent("diff-viewer-app", isDirectory: true)
.appendingPathComponent("webviews-app", isDirectory: true)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Update Swift diff-viewer fixtures for the renamed app bundle

When the Swift CLI tests build their temporary fixture resources, writeTestDiffViewerAssets still creates markdown-viewer/diff-viewer-app, and several CMUXOpenCommandTests assertions still look for cmux-diff-viewer-app/main.mjs; with this lookup now requiring markdown-viewer/webviews-app, those tests either throw Bundled cmux diff viewer app assets not found before generating the viewer or fail the expected asset URL checks. Update the test fixtures/assertions in the same rename so the CLI test suite can pass.

Useful? React with 👍 / 👎.

coderabbitai[bot]
coderabbitai Bot previously requested changes Jun 6, 2026

@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: 3

🤖 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 @.github/workflows/ci.yml:
- Around line 289-296: The CI change introducing an isolated DerivedData path
(the "Prepare isolated DerivedData" step in .github/workflows/ci.yml that
defines DERIVED_DATA_PATH and exports CMUX_DERIVED_DATA_PATH) is unrelated to
the webviews rename and TanStack Router pin, so revert or remove that block from
this PR and move it into a separate commit/PR dedicated to CI/infrastructure
changes; specifically, remove the DERIVED_DATA_PATH creation and the echo
"CMUX_DERIVED_DATA_PATH=..." line from this workflow here, then create a new PR
that adds the Prepare isolated DerivedData step (using RUNNER_TEMP,
GITHUB_RUN_ID, GITHUB_RUN_ATTEMPT) as a standalone change with its own
description and tests so infrastructure changes are traceable and rollbackable
independently.
- Around line 10-12: The workflow currently grants broad write scope via the
permissions setting "actions: write"; since the job only uses
actions/upload-artifact, actions/download-artifact and the
concurrency.cancel-in-progress feature, remove "actions: write" from the
permissions block (leaving actions at the default or setting it to "read") or
add a clear comment/PR description justifying why "actions: write" is required;
update the permissions block in .github/workflows/ci.yml and ensure any
justification references the specific need for actions write scope if you keep
it.

In `@CLI/cmux_open.swift`:
- Around line 942-945: The guard currently accepts paths based only on
FileManager.default.isExecutableFile(atPath: candidate.path) which can be true
for directories; update the check in the routine that returns
canonicalFileURL(candidate) so directory-valued candidates are rejected first.
Use FileManager.default.fileExists(atPath:isDirectory:) (or URL
resourceValues/.isDirectory) to ensure the candidate isDirectory == false before
calling isExecutableFile, and only return canonicalFileURL(candidate) when both
"not a directory" and "isExecutableFile" are satisfied.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 560e1135-223e-4962-9251-8f22ddada793

📥 Commits

Reviewing files that changed from the base of the PR and between b202f5b and e5b4a25.

📒 Files selected for processing (2)
  • .github/workflows/ci.yml
  • CLI/cmux_open.swift

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

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 3

🤖 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 @.github/workflows/ci.yml:
- Around line 289-296: The CI change introducing an isolated DerivedData path
(the "Prepare isolated DerivedData" step in .github/workflows/ci.yml that
defines DERIVED_DATA_PATH and exports CMUX_DERIVED_DATA_PATH) is unrelated to
the webviews rename and TanStack Router pin, so revert or remove that block from
this PR and move it into a separate commit/PR dedicated to CI/infrastructure
changes; specifically, remove the DERIVED_DATA_PATH creation and the echo
"CMUX_DERIVED_DATA_PATH=..." line from this workflow here, then create a new PR
that adds the Prepare isolated DerivedData step (using RUNNER_TEMP,
GITHUB_RUN_ID, GITHUB_RUN_ATTEMPT) as a standalone change with its own
description and tests so infrastructure changes are traceable and rollbackable
independently.
- Around line 10-12: The workflow currently grants broad write scope via the
permissions setting "actions: write"; since the job only uses
actions/upload-artifact, actions/download-artifact and the
concurrency.cancel-in-progress feature, remove "actions: write" from the
permissions block (leaving actions at the default or setting it to "read") or
add a clear comment/PR description justifying why "actions: write" is required;
update the permissions block in .github/workflows/ci.yml and ensure any
justification references the specific need for actions write scope if you keep
it.

In `@CLI/cmux_open.swift`:
- Around line 942-945: The guard currently accepts paths based only on
FileManager.default.isExecutableFile(atPath: candidate.path) which can be true
for directories; update the check in the routine that returns
canonicalFileURL(candidate) so directory-valued candidates are rejected first.
Use FileManager.default.fileExists(atPath:isDirectory:) (or URL
resourceValues/.isDirectory) to ensure the candidate isDirectory == false before
calling isExecutableFile, and only return canonicalFileURL(candidate) when both
"not a directory" and "isExecutableFile" are satisfied.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 560e1135-223e-4962-9251-8f22ddada793

📥 Commits

Reviewing files that changed from the base of the PR and between b202f5b and e5b4a25.

📒 Files selected for processing (2)
  • .github/workflows/ci.yml
  • CLI/cmux_open.swift
🛑 Comments failed to post (3)
.github/workflows/ci.yml (2)

10-12: ⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for workflow steps that might need actions: write permission
rg -n -C3 'actions/(cancel-workflow|upload-artifact|download-artifact)' .github/workflows/ci.yml

Repository: manaflow-ai/cmux

Length of output: 748


🏁 Script executed:

#!/bin/bash
set -euo pipefail
f=".github/workflows/ci.yml"

echo "== Find cancel-in-progress usage =="
rg -n "cancel-in-progress" "$f" || true

echo
echo "== List uses: actions/* in this workflow =="
rg -n "uses:\s*actions/" "$f" || true

echo
echo "== Show top-level permissions block =="
rg -n "^\s*permissions:|^\s*contents:|^\s*actions:" -n "$f" || true

Repository: manaflow-ai/cmux

Length of output: 2489


🌐 Web query:

Do GitHub Actions upload/download artifacts require permissions: actions: write? What permissions are required for actions/upload-artifactandactions/download-artifact?

💡 Result:

GitHub Actions actions/upload-artifact and actions/download-artifact do not require explicit permissions: actions: write to perform standard operations within the current workflow run [1][2]. For standard usage—uploading and downloading artifacts within the same repository and the current workflow run—the actions utilize internal authentication mechanisms (often involving scoped access signatures) that do not require elevated repository permissions [1][2]. The specific permissions required depend on the scope of the action: 1. Standard Operations (Current Run): - No explicit permissions block granting actions: write or actions: read is required for the action to function within the current workflow run [1][2]. 2. Cross-Repository or Cross-Run Operations: - When you need to download artifacts from a different repository or a different workflow run, you must provide a github-token with at least actions: read permissions for the target repository [3][4][2]. - If you need to perform administrative tasks, such as deleting artifacts from other repositories or runs, you would require a token with actions: write permissions [5]. In summary, you do not need actions: write for basic uploading and downloading, and you only need specific actions permissions when extending the scope of these actions beyond the current workflow execution [5][2].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail
f=".github/workflows/ci.yml"

echo "== Any other explicit permissions blocks in jobs? =="
rg -n "^\s*permissions:" "$f" || true

echo
echo "== Any github-token / token inputs passed to actions? =="
rg -n "github-token:|token: *\$\{\{.*\}\}" "$f" || true

echo
echo "== Search for artifact deletion / other actions needing elevated permissions =="
rg -n "delete-artifact|cancel-workflow|workflow.*cancel|octokit|api\.github|rest\.|actions: write" "$f" || true

Repository: manaflow-ai/cmux

Length of output: 288


🌐 Web query:

Does GitHub Actions concurrency cancel-in-progress: truerequirepermissions: actions: write(or anypermissions override), or is it handled by the runner/scheduler automatically?

💡 Result:

You do not need to grant permissions: actions: write (or any explicit permissions override) specifically for concurrency.cancel-in-progress: true. GitHub’s documentation describes cancel-in-progress: true as a native scheduler/server behavior for canceling in-progress runs within the same concurrency group; it does not state any required permissions for this mechanism [1][2]. In contrast, marketplace actions that cancel workflow runs via the Actions API explicitly document requiring actions: write (e.g., cancel-workflow-action/cancel-queued-runs), because those implementations call the API rather than relying on the native concurrency cancel feature [3][4]. So: cancel-in-progress is handled automatically by GitHub Actions’ concurrency controls; permissions: actions: write is only relevant if you’re using an external action/tool that cancels runs through the REST API (or similar), not for the built-in concurrency key itself [1][2].

Citations:


🏁 Script executed:

#!/bin/bash
f=".github/workflows/ci.yml"
sed -n '1,60p' "$f" | cat -n

Repository: manaflow-ai/cmux

Length of output: 2256


🏁 Script executed:

#!/bin/bash
f=".github/workflows/ci.yml"

echo "== Search for any uses that likely need elevated actions: write =="
rg -n "delete-artifact|cancel-workflow|cancel-queued|github\.api|octokit|rest\." "$f" || true

echo
echo "== Search for any explicit workflow/runner cancellation helpers =="
rg -n "cancel-in-progress|cancel-workflow|cancel-queued" "$f" || true

echo
echo "== Search for github-script / actions/github-script usage =="
rg -n "actions/github-script|github-script" "$f" || true

echo
echo "== Search for API delete / artifacts delete commands =="
rg -n "artifact.*delete|delete.*artifact|gh api.*artifact|rest.*actions" "$f" || true

Repository: manaflow-ai/cmux

Length of output: 382


Restrict/justify permissions.actions: write in CI workflow

.github/workflows/ci.yml sets permissions: actions: write (lines 10-12), but the workflow only uses actions/upload-artifact / actions/download-artifact and native concurrency.cancel-in-progress; there are no workflow/API steps found that would require elevated actions: write (e.g., no REST/Octokit calls, artifact deletion, or external cancellation actions). Remove actions: write or add a clear PR justification for why it’s needed at the workflow level.

🧰 Tools
🪛 zizmor (1.25.2)

[error] 12-12: overly broad permissions (excessive-permissions): actions: write is overly broad at the workflow level

(excessive-permissions)


[warning] 12-12: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment

(undocumented-permissions)

🤖 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 @.github/workflows/ci.yml around lines 10 - 12, The workflow currently grants
broad write scope via the permissions setting "actions: write"; since the job
only uses actions/upload-artifact, actions/download-artifact and the
concurrency.cancel-in-progress feature, remove "actions: write" from the
permissions block (leaving actions at the default or setting it to "read") or
add a clear comment/PR description justifying why "actions: write" is required;
update the permissions block in .github/workflows/ci.yml and ensure any
justification references the specific need for actions write scope if you keep
it.

289-296: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

DerivedData isolation is a separate concern from webviews rename.

The addition of isolated DerivedData paths (with RUNNER_TEMP, GITHUB_RUN_ID, and GITHUB_RUN_ATTEMPT) is a solid CI reliability improvement that prevents cache pollution between jobs and retry attempts. However, this change is orthogonal to the PR's stated objectives (renaming diff-viewer to webviews and pinning TanStack Router).

While not harmful, bundling infrastructure improvements with feature changes makes it harder to trace regressions and complicates rollback. Consider separating infrastructure changes into dedicated PRs in the future.

Also applies to: 521-526, 872-877

🤖 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 @.github/workflows/ci.yml around lines 289 - 296, The CI change introducing
an isolated DerivedData path (the "Prepare isolated DerivedData" step in
.github/workflows/ci.yml that defines DERIVED_DATA_PATH and exports
CMUX_DERIVED_DATA_PATH) is unrelated to the webviews rename and TanStack Router
pin, so revert or remove that block from this PR and move it into a separate
commit/PR dedicated to CI/infrastructure changes; specifically, remove the
DERIVED_DATA_PATH creation and the echo "CMUX_DERIVED_DATA_PATH=..." line from
this workflow here, then create a new PR that adds the Prepare isolated
DerivedData step (using RUNNER_TEMP, GITHUB_RUN_ID, GITHUB_RUN_ATTEMPT) as a
standalone change with its own description and tests so infrastructure changes
are traceable and rollbackable independently.
CLI/cmux_open.swift (1)

942-945: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Reject directory-valued runtime executable candidates before accepting tag runtime.

At Line 942, isExecutableFile(atPath:) alone can treat a directory as executable. If that happens, the tagged runtime path is accepted and later launch fails instead of falling back cleanly.

Suggested fix
-        guard FileManager.default.isExecutableFile(atPath: candidate.path) else {
+        var isDirectory: ObjCBool = false
+        guard FileManager.default.fileExists(atPath: candidate.path, isDirectory: &isDirectory),
+              !isDirectory.boolValue,
+              FileManager.default.isExecutableFile(atPath: candidate.path) else {
             return nil
         }

Based on learnings: user-provided/custom executable paths in this repo should verify isDirectory == false before isExecutableFile so invalid directory candidates are rejected and safe fallback remains possible.

🤖 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 `@CLI/cmux_open.swift` around lines 942 - 945, The guard currently accepts
paths based only on FileManager.default.isExecutableFile(atPath: candidate.path)
which can be true for directories; update the check in the routine that returns
canonicalFileURL(candidate) so directory-valued candidates are rejected first.
Use FileManager.default.fileExists(atPath:isDirectory:) (or URL
resourceValues/.isDirectory) to ensure the candidate isDirectory == false before
calling isExecutableFile, and only return canonicalFileURL(candidate) when both
"not a directory" and "isExecutableFile" are satisfied.

Source: Learnings

@lawrencecchen
lawrencecchen dismissed coderabbitai[bot]’s stale review June 6, 2026 11:34

CodeRabbit now posts non-blocking comment reviews (request_changes_workflow=false, #5538).

@lawrencecchen

Copy link
Copy Markdown
Contributor Author

Superseded: main already has the diff-viewer→webviews rename, the pinned @tanstack/react-router 1.170.11, and the verify:tanstack-router script (landed via the webviews split work, e.g. #5613). Closing as part of the editor-gui board reconcile.

This branch was successfully deployed

1 active deployment
Preview – cmux — e5b4a256 Deployed Jun 6, 2026 by vercel[bot]
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