Skip to content

fix(install): rewrite relative skill links for injected ecc namespace - #2399

Merged
affaan-m merged 3 commits into
affaan-m:mainfrom
gaurav0107:fix/2340-bug-installer-injects-ecc-namespace-but
Jul 4, 2026
Merged

affaan-m merged 3 commits into
affaan-m:mainfrom
gaurav0107:fix/2340-bug-installer-injects-ecc-namespace-but

Conversation

@gaurav0107

Copy link
Copy Markdown
Contributor

What Changed

The home/project claude installer injects an ecc/ namespace segment into
managed destinations (skills/<id> -> skills/ecc/<id>, rules/<x> ->
rules/ecc/<x>) but byte-copied markdown content unchanged. This adds a
relative-link rewrite for namespaced markdown so intra-file links resolve to
the file's actual installed location.

  • New pure helper scripts/lib/install/link-rewrite.js (buildInstallIndex +
    rewriteRelativeLinks). The rewrite is derived from the plan's own file
    placements, so a link's corrected target is always exactly where the same
    install puts that file — no hardcoded ecc/../ literal that could drift.
  • Wired into the single copy-file choke point in scripts/lib/install/apply.js,
    gated to markdown whose own install path was namespaced. Everything else is
    still byte-copied unchanged.
  • New tests/lib/install-link-rewrite.test.js (13 cases + a real-content
    integration check over the three affected React skills).

Why This Change

After a profile: full install to ~/.claude, skills that link to a sibling
top-level dir via a source-relative path break. Observed: three React skills
link ../../rules/react/...; post-install the extra ecc/ level makes
../.. resolve to ~/.claude/skills/ (so the link points at
~/.claude/skills/rules/react/..., which does not exist), while the rules
actually land at ~/.claude/rules/ecc/react/.... The correct installed link is
../../../rules/ecc/react/.... Fixes #2340.

Testing Done

  • node tests/run-all.js — 2950/2950 pass (clean env), new file included.
  • tests/lib/install-executor.test.js (10), tests/scripts/install-apply.test.js
    (28), tests/lib/install-targets.test.js (41) — all green (additive change,
    no behavioral drift for non-namespaced/non-markdown files).
  • npx eslint on the changed files — clean.
  • validate-install-manifests, validate-no-personal-paths,
    check-unicode-safety — clean.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)

Security & Quality Checklist

  • No secrets, credentials, or personal absolute paths added
  • Pure, IO-free rewrite helper; conservative — never touches URLs,
    absolute paths, anchors, fenced code blocks, or links to files the plan
    does not install
  • No change to install file placement; non-namespacing adapters
    (cursor/codex/...) are a verified no-op
  • New scripts/lib/ file has a matching tests/lib/ test
  • Conventional commit, <=100-char header

Documentation

No user-facing docs change required; behavior is internal to the installer.
The three affected skill source files are left as-is (their links are correct
for the source layout) — only the installed copies are corrected.

Skill and rule markdown is byte-copied during a claude install, but the
home/project adapters inject an `ecc/` namespace segment
(skills/<id> -> skills/ecc/<id>, rules/<x> -> rules/ecc/<x>). Source-relative
links such as `../../rules/react/hooks.md` therefore broke after install: the
extra level changed what `../..` resolved to, and the link target itself moved
under rules/ecc/.

Rewrite relative links in namespaced markdown so they resolve to the file's
actual installed location, derived from the plan's own file placements (no
hardcoded namespace literal, so the links cannot drift from where files land).
Non-namespacing adapters and links to non-installed targets are left untouched;
URLs, anchors, absolute paths, and fenced code blocks are never rewritten.

Fixes affaan-m#2340
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: cc2d6c8c-6b0f-424a-9aab-bc0af2a99b0b

📥 Commits

Reviewing files that changed from the base of the PR and between e5ef5ae and db853e4.

📒 Files selected for processing (1)
  • tests/lib/install-link-rewrite.test.js
📜 Recent review details
⏰ Context from checks skipped due to timeout. (15)
  • GitHub Check: Greptile Review
  • GitHub Check: Test (ubuntu-latest, Node 18.x, bun)
  • GitHub Check: Test (macos-latest, Node 18.x, npm)
  • GitHub Check: Test (windows-latest, Node 20.x, pnpm)
  • GitHub Check: Test (macos-latest, Node 18.x, bun)
  • GitHub Check: Test (windows-latest, Node 22.x, pnpm)
  • GitHub Check: Test (macos-latest, Node 20.x, pnpm)
  • GitHub Check: Test (macos-latest, Node 18.x, pnpm)
  • GitHub Check: Test (macos-latest, Node 22.x, pnpm)
  • GitHub Check: Test (ubuntu-latest, Node 22.x, bun)
  • GitHub Check: Test (ubuntu-latest, Node 22.x, pnpm)
  • GitHub Check: Test (ubuntu-latest, Node 20.x, bun)
  • GitHub Check: Test (ubuntu-latest, Node 20.x, pnpm)
  • GitHub Check: Test (windows-latest, Node 18.x, pnpm)
  • GitHub Check: Test (ubuntu-latest, Node 18.x, pnpm)
🧰 Additional context used
📓 Path-based instructions (16)
**/*.{js,ts,jsx,tsx,py,java,cs,go,rb,php,scala,kt}

📄 CodeRabbit inference engine (.cursor/rules/common-coding-style.md)

**/*.{js,ts,jsx,tsx,py,java,cs,go,rb,php,scala,kt}: Always create new objects, never mutate existing ones. Use immutable patterns to prevent hidden side effects and enable safe concurrency
Organize code into many small files (200-400 lines typical, 800 lines max) organized by feature/domain rather than by type
Always handle errors explicitly at every level and never silently swallow errors
Always validate all user input before processing at system boundaries
Use schema-based validation where available
Fail fast with clear error messages when validation fails
Never trust external data (API responses, user input, file content)
Ensure code is readable and well-named
Keep functions small (less than 50 lines)
Keep files focused (less than 800 lines)
Avoid deep nesting (more than 4 levels)
Do not use hardcoded values; use constants or configuration instead

Files:

  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php,swift,kt,rs,c,cpp,h,hpp}

📄 CodeRabbit inference engine (.cursor/rules/common-security.md)

No hardcoded secrets (API keys, passwords, tokens) - validate before any commit

Files:

  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php}

📄 CodeRabbit inference engine (.cursor/rules/common-security.md)

**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php}: All user inputs must be validated
Enable CSRF protection on all state-changing endpoints
Verify authentication and authorization for all protected endpoints
Implement rate limiting on all endpoints to prevent abuse
Ensure error messages do not leak sensitive data in responses

Files:

  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php,sql}

📄 CodeRabbit inference engine (.cursor/rules/common-security.md)

Use parameterized queries to prevent SQL injection

Files:

  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts,jsx,tsx,html,php,java,cs,rb,go}

📄 CodeRabbit inference engine (.cursor/rules/common-security.md)

Implement XSS prevention by sanitizing HTML output

Files:

  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php,swift,kt,rs,c,cpp,h,hpp,properties,yml,yaml,json,env,config}

📄 CodeRabbit inference engine (.cursor/rules/common-security.md)

NEVER hardcode secrets in source code - ALWAYS use environment variables or a secret manager

Files:

  • tests/lib/install-link-rewrite.test.js
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/typescript-coding-style.md)

**/*.{ts,tsx,js,jsx}: Use spread operator for immutable updates in TypeScript/JavaScript instead of direct mutation
Use async/await with try-catch for error handling in TypeScript/JavaScript
Use Zod for schema-based input validation in TypeScript/JavaScript
No console.log statements in production code; use proper logging libraries instead

**/*.{ts,tsx,js,jsx}: Auto-format JavaScript/TypeScript files using Prettier after edit
Warn about console.log statements in edited files
Check all modified files for console.log statements before session ends

**/*.{ts,tsx,js,jsx}: Use the ApiResponse interface pattern with generic type parameter: interface ApiResponse<T> { success: boolean; data?: T; error?: string; meta?: { total: number; page: number; limit: number; } }
Implement custom React hooks following the pattern: export a named function with use prefix, generic type parameters, and proper useEffect cleanup for side effects

**/*.{ts,tsx,js,jsx}: Never hardcode secrets; always use environment variables for sensitive credentials like API keys
Throw an error when required environment variables are not configured to fail fast and ensure security prerequisites are met

Use Playwright as the E2E testing framework for critical user flows in TypeScript/JavaScript

Files:

  • tests/lib/install-link-rewrite.test.js
**/*.{test,spec}.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{test,spec}.{js,ts,jsx,tsx}: Write tests before implementation (test-driven development); target 80%+ coverage
Achieve minimum 80% test coverage across all three layers: Unit, Integration, and E2E
Use AAA structure (Arrange / Act / Assert) in tests with descriptive test names that explain behavior under test

Files:

  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,ts,jsx,tsx}: Always create new objects and never mutate in place; return new copies instead
Keep files between 200–400 lines typical, with a maximum of 800 lines
Extract helpers when a file exceeds 200 lines
Handle errors explicitly at every level; never swallow errors silently
Validate all user input before processing; use schema-based validation where available
Never trust external data (API responses, file content, query params); always validate
All user inputs must be validated and sanitized
Error messages must be scrubbed of sensitive internals
Use readable, well-named identifiers in all code
Keep functions under 50 lines
Keep files under 800 lines
Avoid nesting deeper than 4 levels
Implement comprehensive error handling in all code
Do not hardcode values; use constants or environment configuration instead
Do not use in-place mutation; always return new objects or state

Files:

  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts,jsx,tsx,json,env*}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Do not hardcode secrets, API keys, passwords, or tokens

Files:

  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,ts}: Use parameterized queries for all database writes (no string interpolation)
Auth/authz must be checked server-side for every sensitive path
Rate limiting must be applied to all public endpoints

Files:

  • tests/lib/install-link-rewrite.test.js
**/*.{jsx,tsx,js,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

HTML output must be sanitized where applicable

Files:

  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts,env*}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Required environment variables must be validated at startup

Files:

  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts,jsx,tsx,py,java,go,rs,kt,cpp,c,fs}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx,py,java,go,rs,kt,cpp,c,fs}: Write tests before implementation using TDD workflow: write failing test (RED), implement minimal code (GREEN), then refactor (IMPROVE)
Keep functions small (<50 lines) and files focused (<800 lines, typical 200-400 lines)
Avoid deep nesting (>4 levels)

Files:

  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts,jsx,tsx,py,java,go,rs,kt}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx,py,java,go,rs,kt}: Never mutate existing objects; always create new objects with changes applied (Immutability requirement)
Handle errors at every level; provide user-friendly messages in UI code and detailed context in server-side logs
Ensure error messages don't leak sensitive data

Files:

  • tests/lib/install-link-rewrite.test.js
**/*.{jsx,tsx,html,js,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Sanitize HTML output to prevent XSS vulnerabilities

Files:

  • tests/lib/install-link-rewrite.test.js
🔇 Additional comments (1)
tests/lib/install-link-rewrite.test.js (1)

49-50: LGTM!


📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Automatically rewrites relative links and images inside markdown during installation when files are placed into namespaced paths, so references resolve to the correct installed locations.
    • Maintains trailing-slash semantics for directory links and preserves #fragment sections.
  • Bug Fixes
    • Prevents broken relative links in installed markdown, while leaving external, absolute, mailto:, and anchor-only links unchanged.
    • Avoids rewriting inside fenced code blocks.
  • Tests
    • Added unit and integration tests covering rewriting behavior, no-op cases, and namespaced-source detection.

Walkthrough

Adds markdown link rewriting for namespaced installs, wires it into markdown copy operations during install, and adds unit and integration coverage for rewritten relative links.

Changes

Namespaced install link rewriting

Layer / File(s) Summary
link-rewrite.js: index building and rewrite logic
scripts/lib/install/link-rewrite.js
Defines inline-link regex, POSIX path helpers, buildInstallIndex (produces byFile/byDir maps from planned placements), isExternalOrAnchor, resolveInstalledTarget, isNamespacedSource, and rewriteRelativeLinks with fenced-code-block guards, fragment preservation, trailing-slash semantics, and normalization-based no-op checks.
apply.js: link-index wiring into applyInstallPlan
scripts/lib/install/apply.js
Imports the new utilities, adds isMarkdownPath and buildLinkIndexForPlan (returns null when plan data is absent), computes linkIndex once per plan, and intercepts markdown copy-file operations to read, rewrite, and write instead of byte-copying.
Unit and integration tests
tests/lib/install-link-rewrite.test.js
Custom test harness with parametrized unit cases for rewriting, trailing slashes, sibling links, external/absolute/anchor no-ops, fragment preservation, fenced-code-block skipping, nested depth, and identity/not-in-plan no-ops, plus an integration test that builds a real index from createManifestInstallPlan and asserts changed links resolve to installed paths.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • affaan-m

Poem

A link once bent by namespace drift,
now walks the path with a careful lift.
../../rules/ found its way,
and markdown links hold steady today.
🔗

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 46.67% 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 matches the main change: fixing install-time rewrites for relative skill links under the injected ecc namespace.
Description check ✅ Passed The description is clearly about the same installer link-rewrite fix and its tests, so it is related to the changeset.
Linked Issues check ✅ Passed The changes implement #2340 by rewriting relative markdown links during install for namespaced paths and covering it with tests.
Out of Scope Changes check ✅ Passed The added helper, apply hook, and tests all support the linked install-link rewrite fix with no obvious unrelated changes.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


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.

@ecc-tools

ecc-tools Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR.

@gaurav0107
gaurav0107 marked this pull request as ready for review June 30, 2026 05:35
@gaurav0107
gaurav0107 requested a review from affaan-m as a code owner June 30, 2026 05:35
@greptile-apps

greptile-apps Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes relative markdown links for namespaced Claude installs. The main changes are:

  • Adds a pure install link index and rewrite helper.
  • Rewrites only namespaced markdown files during install.
  • Keeps identity-mapped markdown and non-markdown files on the byte-copy path.
  • Adds tests for rewritten links, no-op paths, fragments, fences, and real React skill content.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
scripts/lib/install/apply.js Builds the link index and sends only namespaced markdown files through the rewrite path.
scripts/lib/install/link-rewrite.js Adds the helper that maps planned install paths and rewrites matching relative markdown links.
tests/lib/install-link-rewrite.test.js Adds coverage for rewritten links, no-op install paths, ignored link forms, and real React skill content.

Reviews (3): Last reviewed commit: "test(install): emit failure stack in the..." | Re-trigger Greptile

Comment thread scripts/lib/install/apply.js
…path

Address review feedback: the markdown branch in applyInstallPlan diverted every
copy-file markdown operation through read+rewrite+write, so identity-mapped
markdown (source path == install path, no namespace injected) lost byte-for-byte
content and source mode bits even though no link rewrite was needed.

Gate the rewrite on isNamespacedSource() so only files whose install path
actually changed (e.g. skills/x -> skills/ecc/x) leave the copyFileSync path;
everything else is copied verbatim as before.

@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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/lib/install/apply.js`:
- Around line 177-193: The install planning in apply.js still accepts
manifest-derived relative paths that may contain .. or absolute segments,
allowing path.join() in the operation-building flow to escape the intended
roots. Add validation in the path normalization/planning path before creating
copy-file operations so normalizeRelativePath(), sourcePath, and destinationPath
are constrained to options.sourceRoot and targetRoot, rejecting any path that is
not contained within those roots.

In `@tests/lib/install-link-rewrite.test.js`:
- Around line 52-208: `runTests` is too large because it mixes case definitions,
execution, and result bookkeeping in one function. Split the individual
`test(...)` cases into a data-driven list or small helper builders, and keep
`runTests` focused on iterating the cases and reporting `passed`/`failed`. Use
the existing symbols `runTests`, `test`, `rewriteRelativeLinks`, and
`buildInstallIndex` to reorganize the logic without changing test behavior.
- Around line 40-49: The custom test runner’s `test` helper is only printing
`error.message`, which drops the stack and assertion diff for failures. Update
the failure path in `test` to explicitly handle the caught error by emitting the
full error stack to stderr (with a fallback to the error itself if no stack is
present), and keep the failure context tied to the existing `test` function so
rewrite failures remain diagnosable.
🪄 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: aa1bc03e-c4ef-4a2c-8a07-6e36655a5482

📥 Commits

Reviewing files that changed from the base of the PR and between 81af407 and f86b826.

📒 Files selected for processing (3)
  • scripts/lib/install/apply.js
  • scripts/lib/install/link-rewrite.js
  • tests/lib/install-link-rewrite.test.js
📜 Review details
⏰ Context from checks skipped due to timeout. (10)
  • GitHub Check: Greptile Review
  • GitHub Check: Test (windows-latest, Node 22.x, pnpm)
  • GitHub Check: Test (macos-latest, Node 18.x, pnpm)
  • GitHub Check: Test (macos-latest, Node 22.x, pnpm)
  • GitHub Check: Test (macos-latest, Node 18.x, bun)
  • GitHub Check: Test (macos-latest, Node 20.x, pnpm)
  • GitHub Check: Test (windows-latest, Node 20.x, pnpm)
  • GitHub Check: Test (windows-latest, Node 18.x, pnpm)
  • GitHub Check: Test (ubuntu-latest, Node 18.x, bun)
  • GitHub Check: Test (ubuntu-latest, Node 18.x, pnpm)
🧰 Additional context used
📓 Path-based instructions (19)
**/*.{js,ts,jsx,tsx,py,java,cs,go,rb,php,scala,kt}

📄 CodeRabbit inference engine (.cursor/rules/common-coding-style.md)

**/*.{js,ts,jsx,tsx,py,java,cs,go,rb,php,scala,kt}: Always create new objects, never mutate existing ones. Use immutable patterns to prevent hidden side effects and enable safe concurrency
Organize code into many small files (200-400 lines typical, 800 lines max) organized by feature/domain rather than by type
Always handle errors explicitly at every level and never silently swallow errors
Always validate all user input before processing at system boundaries
Use schema-based validation where available
Fail fast with clear error messages when validation fails
Never trust external data (API responses, user input, file content)
Ensure code is readable and well-named
Keep functions small (less than 50 lines)
Keep files focused (less than 800 lines)
Avoid deep nesting (more than 4 levels)
Do not use hardcoded values; use constants or configuration instead

Files:

  • scripts/lib/install/link-rewrite.js
  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php,swift,kt,rs,c,cpp,h,hpp}

📄 CodeRabbit inference engine (.cursor/rules/common-security.md)

No hardcoded secrets (API keys, passwords, tokens) - validate before any commit

Files:

  • scripts/lib/install/link-rewrite.js
  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php}

📄 CodeRabbit inference engine (.cursor/rules/common-security.md)

**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php}: All user inputs must be validated
Enable CSRF protection on all state-changing endpoints
Verify authentication and authorization for all protected endpoints
Implement rate limiting on all endpoints to prevent abuse
Ensure error messages do not leak sensitive data in responses

Files:

  • scripts/lib/install/link-rewrite.js
  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php,sql}

📄 CodeRabbit inference engine (.cursor/rules/common-security.md)

Use parameterized queries to prevent SQL injection

Files:

  • scripts/lib/install/link-rewrite.js
  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts,jsx,tsx,html,php,java,cs,rb,go}

📄 CodeRabbit inference engine (.cursor/rules/common-security.md)

Implement XSS prevention by sanitizing HTML output

Files:

  • scripts/lib/install/link-rewrite.js
  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php,swift,kt,rs,c,cpp,h,hpp,properties,yml,yaml,json,env,config}

📄 CodeRabbit inference engine (.cursor/rules/common-security.md)

NEVER hardcode secrets in source code - ALWAYS use environment variables or a secret manager

Files:

  • scripts/lib/install/link-rewrite.js
  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/typescript-coding-style.md)

**/*.{ts,tsx,js,jsx}: Use spread operator for immutable updates in TypeScript/JavaScript instead of direct mutation
Use async/await with try-catch for error handling in TypeScript/JavaScript
Use Zod for schema-based input validation in TypeScript/JavaScript
No console.log statements in production code; use proper logging libraries instead

**/*.{ts,tsx,js,jsx}: Auto-format JavaScript/TypeScript files using Prettier after edit
Warn about console.log statements in edited files
Check all modified files for console.log statements before session ends

**/*.{ts,tsx,js,jsx}: Use the ApiResponse interface pattern with generic type parameter: interface ApiResponse<T> { success: boolean; data?: T; error?: string; meta?: { total: number; page: number; limit: number; } }
Implement custom React hooks following the pattern: export a named function with use prefix, generic type parameters, and proper useEffect cleanup for side effects

**/*.{ts,tsx,js,jsx}: Never hardcode secrets; always use environment variables for sensitive credentials like API keys
Throw an error when required environment variables are not configured to fail fast and ensure security prerequisites are met

Use Playwright as the E2E testing framework for critical user flows in TypeScript/JavaScript

Files:

  • scripts/lib/install/link-rewrite.js
  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
{package.json,*.config.js,scripts/**/*.js}

📄 CodeRabbit inference engine (CLAUDE.md)

Package manager detection should support npm, pnpm, yarn, and bun, with configuration via CLAUDE_PACKAGE_MANAGER environment variable or project config.

Files:

  • scripts/lib/install/link-rewrite.js
  • scripts/lib/install/apply.js
scripts/**/*.js

📄 CodeRabbit inference engine (CLAUDE.md)

Ensure cross-platform support for Windows, macOS, and Linux via Node.js scripts in the scripts/ directory.

Files:

  • scripts/lib/install/link-rewrite.js
  • scripts/lib/install/apply.js
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,ts,jsx,tsx}: Always create new objects and never mutate in place; return new copies instead
Keep files between 200–400 lines typical, with a maximum of 800 lines
Extract helpers when a file exceeds 200 lines
Handle errors explicitly at every level; never swallow errors silently
Validate all user input before processing; use schema-based validation where available
Never trust external data (API responses, file content, query params); always validate
All user inputs must be validated and sanitized
Error messages must be scrubbed of sensitive internals
Use readable, well-named identifiers in all code
Keep functions under 50 lines
Keep files under 800 lines
Avoid nesting deeper than 4 levels
Implement comprehensive error handling in all code
Do not hardcode values; use constants or environment configuration instead
Do not use in-place mutation; always return new objects or state

Files:

  • scripts/lib/install/link-rewrite.js
  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts,jsx,tsx,json,env*}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Do not hardcode secrets, API keys, passwords, or tokens

Files:

  • scripts/lib/install/link-rewrite.js
  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,ts}: Use parameterized queries for all database writes (no string interpolation)
Auth/authz must be checked server-side for every sensitive path
Rate limiting must be applied to all public endpoints

Files:

  • scripts/lib/install/link-rewrite.js
  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
**/*.{jsx,tsx,js,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

HTML output must be sanitized where applicable

Files:

  • scripts/lib/install/link-rewrite.js
  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts,env*}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Required environment variables must be validated at startup

Files:

  • scripts/lib/install/link-rewrite.js
  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts,jsx,tsx,py,java,go,rs,kt,cpp,c,fs}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx,py,java,go,rs,kt,cpp,c,fs}: Write tests before implementation using TDD workflow: write failing test (RED), implement minimal code (GREEN), then refactor (IMPROVE)
Keep functions small (<50 lines) and files focused (<800 lines, typical 200-400 lines)
Avoid deep nesting (>4 levels)

Files:

  • scripts/lib/install/link-rewrite.js
  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
**/*.{js,ts,jsx,tsx,py,java,go,rs,kt}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx,py,java,go,rs,kt}: Never mutate existing objects; always create new objects with changes applied (Immutability requirement)
Handle errors at every level; provide user-friendly messages in UI code and detailed context in server-side logs
Ensure error messages don't leak sensitive data

Files:

  • scripts/lib/install/link-rewrite.js
  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
**/*.{jsx,tsx,html,js,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Sanitize HTML output to prevent XSS vulnerabilities

Files:

  • scripts/lib/install/link-rewrite.js
  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
{scripts,bin}/**

⚙️ CodeRabbit configuration file

{scripts,bin}/**: Focus on command injection, unsafe subprocess usage, path traversal, SSRF, secret exposure, and missing tests for new CLI behavior.

Files:

  • scripts/lib/install/link-rewrite.js
  • scripts/lib/install/apply.js
**/*.{test,spec}.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{test,spec}.{js,ts,jsx,tsx}: Write tests before implementation (test-driven development); target 80%+ coverage
Achieve minimum 80% test coverage across all three layers: Unit, Integration, and E2E
Use AAA structure (Arrange / Act / Assert) in tests with descriptive test names that explain behavior under test

Files:

  • tests/lib/install-link-rewrite.test.js
🪛 ast-grep (0.44.0)
scripts/lib/install/apply.js

[warning] 186-186: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFileSync(operation.sourcePath, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename)


[warning] 189-189: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.writeFileSync(operation.destinationPath, rewritten, 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename)

tests/lib/install-link-rewrite.test.js

[warning] 179-179: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFileSync(path.join(REPO_ROOT, sourceRel), 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename)

🪛 OpenGrep (1.23.0)
tests/lib/install-link-rewrite.test.js

[ERROR] 171-171: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)

🔇 Additional comments (3)
scripts/lib/install/link-rewrite.js (2)

29-95: LGTM!


100-164: LGTM!

scripts/lib/install/apply.js (1)

8-31: LGTM!

Comment thread scripts/lib/install/apply.js
Comment thread tests/lib/install-link-rewrite.test.js
Comment thread tests/lib/install-link-rewrite.test.js
@ecc-tools

ecc-tools Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR.

Address review feedback: the local test() harness logged only error.message,
so a failing assertion lost its source line and diff. Print error.stack on
stderr on failure so broken rewrite cases stay diagnosable.

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

Caution

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

⚠️ Outside diff range comments (1)
scripts/lib/install/link-rewrite.js (1)

42-58: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Restrict namespaced detection to real segment insertion.

buildInstallIndex() currently records any non-identity directory remap, and isNamespacedSource() returns true for any source whose installed path merely differs. Because applyInstallPlan() uses that boolean to leave the byte-copy path, a markdown file that is renamed or relocated for some other reason will also be rewritten as if an ecc/ segment had been injected, which can produce wrong relative links. Only mark mappings as namespaced when the destination preserves the same source suffix and adds extra path segments.

Proposed fix
+function hasInsertedSegments(sourceRel, destRel) {
+  const sourceParts = sourceRel.split('/');
+  const destParts = destRel.split('/');
+  if (destParts.length <= sourceParts.length) {
+    return false;
+  }
+
+  for (let pivot = 0; pivot < sourceParts.length; pivot += 1) {
+    const samePrefix =
+      sourceParts.slice(0, pivot).join('/') === destParts.slice(0, pivot).join('/');
+    const sameSuffix =
+      sourceParts.slice(pivot).join('/') ===
+      destParts.slice(destParts.length - (sourceParts.length - pivot)).join('/');
+    if (samePrefix && sameSuffix) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
 function buildInstallIndex(fileMappings) {
   const byFile = new Map();
   const byDir = new Map();
@@
-      if (sourceDir !== destDir) {
+      if (
+        sourceDir !== destDir
+        && sourceParts.slice(depth).join('/') ===
+          destParts.slice(destParts.length - (sourceParts.length - depth)).join('/')
+      ) {
         byDir.set(sourceDir, destDir);
       }
     }
   }
@@
 function isNamespacedSource(sourceRel, index) {
   const normalizedSource = toPosix(sourceRel);
   const installedSource = index && index.byFile.get(normalizedSource);
-  return Boolean(installedSource) && installedSource !== normalizedSource;
+  return Boolean(installedSource)
+    && installedSource !== normalizedSource
+    && hasInsertedSegments(normalizedSource, installedSource);
 }

Also applies to: 100-103

🤖 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 `@scripts/lib/install/link-rewrite.js` around lines 42 - 58, The namespaced
detection in buildInstallIndex()/isNamespacedSource() is too broad because it
treats any non-identity remap as namespace insertion. Update the mapping logic
in buildInstallIndex so it only records a source as namespaced when the
destination keeps the same source suffix and inserts extra path segments, and
make isNamespacedSource rely on that stricter check. This keeps applyInstallPlan
from leaving the byte-copy path for files that were merely renamed or relocated,
so only true inserted-segment cases get rewritten.
🤖 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 `@scripts/lib/install/link-rewrite.js`:
- Around line 42-58: The namespaced detection in
buildInstallIndex()/isNamespacedSource() is too broad because it treats any
non-identity remap as namespace insertion. Update the mapping logic in
buildInstallIndex so it only records a source as namespaced when the destination
keeps the same source suffix and inserts extra path segments, and make
isNamespacedSource rely on that stricter check. This keeps applyInstallPlan from
leaving the byte-copy path for files that were merely renamed or relocated, so
only true inserted-segment cases get rewritten.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: bd57d668-1e53-4f2a-8c65-68f731e24d65

📥 Commits

Reviewing files that changed from the base of the PR and between f86b826 and e5ef5ae.

📒 Files selected for processing (3)
  • scripts/lib/install/apply.js
  • scripts/lib/install/link-rewrite.js
  • tests/lib/install-link-rewrite.test.js
📜 Review details
⏰ Context from checks skipped due to timeout. (15)
  • GitHub Check: Greptile Review
  • GitHub Check: Test (windows-latest, Node 20.x, pnpm)
  • GitHub Check: Test (macos-latest, Node 22.x, pnpm)
  • GitHub Check: Test (macos-latest, Node 20.x, bun)
  • GitHub Check: Test (ubuntu-latest, Node 20.x, bun)
  • GitHub Check: Test (macos-latest, Node 18.x, bun)
  • GitHub Check: Test (macos-latest, Node 20.x, pnpm)
  • GitHub Check: Test (windows-latest, Node 22.x, pnpm)
  • GitHub Check: Test (ubuntu-latest, Node 18.x, bun)
  • GitHub Check: Test (ubuntu-latest, Node 22.x, bun)
  • GitHub Check: Test (ubuntu-latest, Node 22.x, pnpm)
  • GitHub Check: Test (macos-latest, Node 18.x, pnpm)
  • GitHub Check: Test (ubuntu-latest, Node 20.x, pnpm)
  • GitHub Check: Test (ubuntu-latest, Node 18.x, pnpm)
  • GitHub Check: Test (windows-latest, Node 18.x, pnpm)
🧰 Additional context used
📓 Path-based instructions (19)
**/*.{js,ts,jsx,tsx,py,java,cs,go,rb,php,scala,kt}

📄 CodeRabbit inference engine (.cursor/rules/common-coding-style.md)

**/*.{js,ts,jsx,tsx,py,java,cs,go,rb,php,scala,kt}: Always create new objects, never mutate existing ones. Use immutable patterns to prevent hidden side effects and enable safe concurrency
Organize code into many small files (200-400 lines typical, 800 lines max) organized by feature/domain rather than by type
Always handle errors explicitly at every level and never silently swallow errors
Always validate all user input before processing at system boundaries
Use schema-based validation where available
Fail fast with clear error messages when validation fails
Never trust external data (API responses, user input, file content)
Ensure code is readable and well-named
Keep functions small (less than 50 lines)
Keep files focused (less than 800 lines)
Avoid deep nesting (more than 4 levels)
Do not use hardcoded values; use constants or configuration instead

Files:

  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
  • scripts/lib/install/link-rewrite.js
**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php,swift,kt,rs,c,cpp,h,hpp}

📄 CodeRabbit inference engine (.cursor/rules/common-security.md)

No hardcoded secrets (API keys, passwords, tokens) - validate before any commit

Files:

  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
  • scripts/lib/install/link-rewrite.js
**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php}

📄 CodeRabbit inference engine (.cursor/rules/common-security.md)

**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php}: All user inputs must be validated
Enable CSRF protection on all state-changing endpoints
Verify authentication and authorization for all protected endpoints
Implement rate limiting on all endpoints to prevent abuse
Ensure error messages do not leak sensitive data in responses

Files:

  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
  • scripts/lib/install/link-rewrite.js
**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php,sql}

📄 CodeRabbit inference engine (.cursor/rules/common-security.md)

Use parameterized queries to prevent SQL injection

Files:

  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
  • scripts/lib/install/link-rewrite.js
**/*.{js,ts,jsx,tsx,html,php,java,cs,rb,go}

📄 CodeRabbit inference engine (.cursor/rules/common-security.md)

Implement XSS prevention by sanitizing HTML output

Files:

  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
  • scripts/lib/install/link-rewrite.js
**/*.{js,ts,jsx,tsx,py,java,cs,rb,go,php,swift,kt,rs,c,cpp,h,hpp,properties,yml,yaml,json,env,config}

📄 CodeRabbit inference engine (.cursor/rules/common-security.md)

NEVER hardcode secrets in source code - ALWAYS use environment variables or a secret manager

Files:

  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
  • scripts/lib/install/link-rewrite.js
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/typescript-coding-style.md)

**/*.{ts,tsx,js,jsx}: Use spread operator for immutable updates in TypeScript/JavaScript instead of direct mutation
Use async/await with try-catch for error handling in TypeScript/JavaScript
Use Zod for schema-based input validation in TypeScript/JavaScript
No console.log statements in production code; use proper logging libraries instead

**/*.{ts,tsx,js,jsx}: Auto-format JavaScript/TypeScript files using Prettier after edit
Warn about console.log statements in edited files
Check all modified files for console.log statements before session ends

**/*.{ts,tsx,js,jsx}: Use the ApiResponse interface pattern with generic type parameter: interface ApiResponse<T> { success: boolean; data?: T; error?: string; meta?: { total: number; page: number; limit: number; } }
Implement custom React hooks following the pattern: export a named function with use prefix, generic type parameters, and proper useEffect cleanup for side effects

**/*.{ts,tsx,js,jsx}: Never hardcode secrets; always use environment variables for sensitive credentials like API keys
Throw an error when required environment variables are not configured to fail fast and ensure security prerequisites are met

Use Playwright as the E2E testing framework for critical user flows in TypeScript/JavaScript

Files:

  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
  • scripts/lib/install/link-rewrite.js
{package.json,*.config.js,scripts/**/*.js}

📄 CodeRabbit inference engine (CLAUDE.md)

Package manager detection should support npm, pnpm, yarn, and bun, with configuration via CLAUDE_PACKAGE_MANAGER environment variable or project config.

Files:

  • scripts/lib/install/apply.js
  • scripts/lib/install/link-rewrite.js
scripts/**/*.js

📄 CodeRabbit inference engine (CLAUDE.md)

Ensure cross-platform support for Windows, macOS, and Linux via Node.js scripts in the scripts/ directory.

Files:

  • scripts/lib/install/apply.js
  • scripts/lib/install/link-rewrite.js
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,ts,jsx,tsx}: Always create new objects and never mutate in place; return new copies instead
Keep files between 200–400 lines typical, with a maximum of 800 lines
Extract helpers when a file exceeds 200 lines
Handle errors explicitly at every level; never swallow errors silently
Validate all user input before processing; use schema-based validation where available
Never trust external data (API responses, file content, query params); always validate
All user inputs must be validated and sanitized
Error messages must be scrubbed of sensitive internals
Use readable, well-named identifiers in all code
Keep functions under 50 lines
Keep files under 800 lines
Avoid nesting deeper than 4 levels
Implement comprehensive error handling in all code
Do not hardcode values; use constants or environment configuration instead
Do not use in-place mutation; always return new objects or state

Files:

  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
  • scripts/lib/install/link-rewrite.js
**/*.{js,ts,jsx,tsx,json,env*}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Do not hardcode secrets, API keys, passwords, or tokens

Files:

  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
  • scripts/lib/install/link-rewrite.js
**/*.{js,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,ts}: Use parameterized queries for all database writes (no string interpolation)
Auth/authz must be checked server-side for every sensitive path
Rate limiting must be applied to all public endpoints

Files:

  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
  • scripts/lib/install/link-rewrite.js
**/*.{jsx,tsx,js,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

HTML output must be sanitized where applicable

Files:

  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
  • scripts/lib/install/link-rewrite.js
**/*.{js,ts,env*}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Required environment variables must be validated at startup

Files:

  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
  • scripts/lib/install/link-rewrite.js
**/*.{js,ts,jsx,tsx,py,java,go,rs,kt,cpp,c,fs}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx,py,java,go,rs,kt,cpp,c,fs}: Write tests before implementation using TDD workflow: write failing test (RED), implement minimal code (GREEN), then refactor (IMPROVE)
Keep functions small (<50 lines) and files focused (<800 lines, typical 200-400 lines)
Avoid deep nesting (>4 levels)

Files:

  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
  • scripts/lib/install/link-rewrite.js
**/*.{js,ts,jsx,tsx,py,java,go,rs,kt}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx,py,java,go,rs,kt}: Never mutate existing objects; always create new objects with changes applied (Immutability requirement)
Handle errors at every level; provide user-friendly messages in UI code and detailed context in server-side logs
Ensure error messages don't leak sensitive data

Files:

  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
  • scripts/lib/install/link-rewrite.js
**/*.{jsx,tsx,html,js,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Sanitize HTML output to prevent XSS vulnerabilities

Files:

  • scripts/lib/install/apply.js
  • tests/lib/install-link-rewrite.test.js
  • scripts/lib/install/link-rewrite.js
{scripts,bin}/**

⚙️ CodeRabbit configuration file

{scripts,bin}/**: Focus on command injection, unsafe subprocess usage, path traversal, SSRF, secret exposure, and missing tests for new CLI behavior.

Files:

  • scripts/lib/install/apply.js
  • scripts/lib/install/link-rewrite.js
**/*.{test,spec}.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{test,spec}.{js,ts,jsx,tsx}: Write tests before implementation (test-driven development); target 80%+ coverage
Achieve minimum 80% test coverage across all three layers: Unit, Integration, and E2E
Use AAA structure (Arrange / Act / Assert) in tests with descriptive test names that explain behavior under test

Files:

  • tests/lib/install-link-rewrite.test.js

@ecc-tools

ecc-tools Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR.

@gaurav0107

gaurav0107 commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

Quick note: these CI reds aren't from this PR. main itself is failing because its lockfile is out of sync with the eslint 10 bump, so npm ci errors before any test runs. #2402 fixes that by resyncing the lockfiles. The bun/pnpm jobs here (including this PR's new tests) are green.

The leftover Windows and Python Tests reds are separate, already-existing issues (a bash-detection test and a missing pyyaml), not related to this change.

@affaan-m
affaan-m merged commit 0a926b4 into affaan-m:main Jul 4, 2026
15 of 41 checks passed
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.

bug: installer injects 'ecc/' namespace but doesn't rewrite '../../rules/...' links in skills (broken after install)

2 participants