intentpatch 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.ko.md +43 -9
  2. package/README.md +34 -9
  3. package/dist/application/ports/module-reference-extractor.d.ts +1 -0
  4. package/dist/application/ports/module-reference-extractor.d.ts.map +1 -1
  5. package/dist/application/ports/parse-failure.d.ts +7 -0
  6. package/dist/application/ports/parse-failure.d.ts.map +1 -0
  7. package/dist/application/ports/parse-failure.js +5 -0
  8. package/dist/application/ports/parse-failure.js.map +1 -0
  9. package/dist/application/ports/pnpm-lock-parser.d.ts +20 -0
  10. package/dist/application/ports/pnpm-lock-parser.d.ts.map +1 -0
  11. package/dist/application/ports/pnpm-lock-parser.js +2 -0
  12. package/dist/application/ports/pnpm-lock-parser.js.map +1 -0
  13. package/dist/application/ports/pnpm-workspace-parser.d.ts +14 -0
  14. package/dist/application/ports/pnpm-workspace-parser.d.ts.map +1 -0
  15. package/dist/application/ports/pnpm-workspace-parser.js +2 -0
  16. package/dist/application/ports/pnpm-workspace-parser.js.map +1 -0
  17. package/dist/application/rules/added-dependency-usage-rule.d.ts +16 -0
  18. package/dist/application/rules/added-dependency-usage-rule.d.ts.map +1 -0
  19. package/dist/application/rules/added-dependency-usage-rule.js +98 -0
  20. package/dist/application/rules/added-dependency-usage-rule.js.map +1 -0
  21. package/dist/application/rules/npm-workspace-dependency-rule.d.ts.map +1 -1
  22. package/dist/application/rules/npm-workspace-dependency-rule.js +10 -58
  23. package/dist/application/rules/npm-workspace-dependency-rule.js.map +1 -1
  24. package/dist/application/rules/package-dependency-rule.d.ts.map +1 -1
  25. package/dist/application/rules/package-dependency-rule.js +1 -3
  26. package/dist/application/rules/package-dependency-rule.js.map +1 -1
  27. package/dist/application/rules/pnpm-lockfile-rule.d.ts +12 -0
  28. package/dist/application/rules/pnpm-lockfile-rule.d.ts.map +1 -0
  29. package/dist/application/rules/pnpm-lockfile-rule.js +119 -0
  30. package/dist/application/rules/pnpm-lockfile-rule.js.map +1 -0
  31. package/dist/application/rules/pnpm-workspace-dependency-rule.d.ts +12 -0
  32. package/dist/application/rules/pnpm-workspace-dependency-rule.d.ts.map +1 -0
  33. package/dist/application/rules/pnpm-workspace-dependency-rule.js +59 -0
  34. package/dist/application/rules/pnpm-workspace-dependency-rule.js.map +1 -0
  35. package/dist/application/services/workspace-manifest-analysis.d.ts +12 -0
  36. package/dist/application/services/workspace-manifest-analysis.d.ts.map +1 -0
  37. package/dist/application/services/workspace-manifest-analysis.js +60 -0
  38. package/dist/application/services/workspace-manifest-analysis.js.map +1 -0
  39. package/dist/domain/value-guards.d.ts +3 -0
  40. package/dist/domain/value-guards.d.ts.map +1 -0
  41. package/dist/domain/value-guards.js +5 -0
  42. package/dist/domain/value-guards.js.map +1 -0
  43. package/dist/infrastructure/config/json-change-contract-loader.d.ts.map +1 -1
  44. package/dist/infrastructure/config/json-change-contract-loader.js +1 -3
  45. package/dist/infrastructure/config/json-change-contract-loader.js.map +1 -1
  46. package/dist/infrastructure/config/text-intent-loader.d.ts +5 -0
  47. package/dist/infrastructure/config/text-intent-loader.d.ts.map +1 -0
  48. package/dist/infrastructure/config/text-intent-loader.js +30 -0
  49. package/dist/infrastructure/config/text-intent-loader.js.map +1 -0
  50. package/dist/infrastructure/git/git-file-snapshot-source.d.ts.map +1 -1
  51. package/dist/infrastructure/git/git-file-snapshot-source.js +3 -1
  52. package/dist/infrastructure/git/git-file-snapshot-source.js.map +1 -1
  53. package/dist/infrastructure/npm/npm-package-lock-parser.d.ts.map +1 -1
  54. package/dist/infrastructure/npm/npm-package-lock-parser.js +2 -6
  55. package/dist/infrastructure/npm/npm-package-lock-parser.js.map +1 -1
  56. package/dist/infrastructure/pnpm/pnpm-lock-parser.d.ts +6 -0
  57. package/dist/infrastructure/pnpm/pnpm-lock-parser.d.ts.map +1 -0
  58. package/dist/infrastructure/pnpm/pnpm-lock-parser.js +122 -0
  59. package/dist/infrastructure/pnpm/pnpm-lock-parser.js.map +1 -0
  60. package/dist/infrastructure/pnpm/pnpm-workspace-parser.d.ts +6 -0
  61. package/dist/infrastructure/pnpm/pnpm-workspace-parser.d.ts.map +1 -0
  62. package/dist/infrastructure/pnpm/pnpm-workspace-parser.js +62 -0
  63. package/dist/infrastructure/pnpm/pnpm-workspace-parser.js.map +1 -0
  64. package/dist/infrastructure/typescript/package-module-reference-extractor.d.ts +7 -0
  65. package/dist/infrastructure/typescript/package-module-reference-extractor.d.ts.map +1 -0
  66. package/dist/infrastructure/typescript/package-module-reference-extractor.js +68 -0
  67. package/dist/infrastructure/typescript/package-module-reference-extractor.js.map +1 -0
  68. package/dist/infrastructure/typescript/typescript-config-loader.d.ts.map +1 -1
  69. package/dist/infrastructure/typescript/typescript-config-loader.js +1 -3
  70. package/dist/infrastructure/typescript/typescript-config-loader.js.map +1 -1
  71. package/dist/presentation/analyze-repository.d.ts +2 -0
  72. package/dist/presentation/analyze-repository.d.ts.map +1 -1
  73. package/dist/presentation/analyze-repository.js +21 -2
  74. package/dist/presentation/analyze-repository.js.map +1 -1
  75. package/dist/presentation/cli/arguments.d.ts +1 -0
  76. package/dist/presentation/cli/arguments.d.ts.map +1 -1
  77. package/dist/presentation/cli/arguments.js +7 -0
  78. package/dist/presentation/cli/arguments.js.map +1 -1
  79. package/dist/presentation/cli/main.js +5 -0
  80. package/dist/presentation/cli/main.js.map +1 -1
  81. package/dist/presentation/github/action-inputs.d.ts +2 -0
  82. package/dist/presentation/github/action-inputs.d.ts.map +1 -1
  83. package/dist/presentation/github/action-inputs.js +10 -0
  84. package/dist/presentation/github/action-inputs.js.map +1 -1
  85. package/dist/presentation/github/pr-body-intent.d.ts +3 -0
  86. package/dist/presentation/github/pr-body-intent.d.ts.map +1 -0
  87. package/dist/presentation/github/pr-body-intent.js +15 -0
  88. package/dist/presentation/github/pr-body-intent.js.map +1 -0
  89. package/dist/presentation/github/run-action.d.ts.map +1 -1
  90. package/dist/presentation/github/run-action.js +10 -0
  91. package/dist/presentation/github/run-action.js.map +1 -1
  92. package/package.json +3 -2
package/README.ko.md CHANGED
@@ -21,7 +21,7 @@ LLM 없이도 재현 가능한 분석을 제공하고, AI 설명 기능은 선
21
21
 
22
22
  ## 빠른 시작
23
23
 
24
- Node.js 20 이상과 Git이 설치되어 있어야 합니다. npm에 공개된 v0.2.0은 전역 설치 없이
24
+ Node.js 20 이상과 Git이 설치되어 있어야 합니다. npm에 공개된 v0.3.0은 전역 설치 없이
25
25
  실행할 수 있습니다.
26
26
 
27
27
  ```bash
@@ -67,7 +67,7 @@ jobs:
67
67
 
68
68
  - name: Analyze pull request
69
69
  id: intentpatch
70
- uses: xx2xxjaeil/intent-patch@v0.2.0
70
+ uses: xx2xxjaeil/intent-patch@v0.3.0
71
71
  with:
72
72
  fail-on: high
73
73
 
@@ -79,8 +79,9 @@ jobs:
79
79
  path: intentpatch-report
80
80
  ```
81
81
 
82
- Action은 릴리스 버전이나 불변 commit SHA로 고정하는 방식을 권장합니다. v0.2.0에는 TypeScript
83
- 경로 별칭과 npm lockfile/workspace 분석이 포함되며, `@main`은 미릴리스 변경을 따라갑니다.
82
+ Action은 릴리스 버전이나 불변 commit SHA로 고정하는 방식을 권장합니다. v0.3.0에는 pnpm
83
+ lockfile/workspace 분석, 새 의존성의 정적 사용 검토, 명시적 요청문 입력이 포함됩니다.
84
+ `@main`은 미릴리스 변경을 따라갑니다.
84
85
  Action은 PR·push 이벤트의 commit 범위를 자동으로 선택하고 다음 결과를 남깁니다.
85
86
 
86
87
  - GitHub Actions Job Summary의 Markdown 보고서
@@ -127,6 +128,11 @@ LOW 구현체가 하나뿐인 추상화 추가
127
128
  분석 결과는 단순한 경고 문구가 아니라 관련 파일, 규칙 ID, 판단 근거와 함께 제공하는 것을
128
129
  원칙으로 합니다.
129
130
 
131
+ 실제 IntentPatch 커밋을 분석한 [독립 실행형 HTML 예시](./docs/examples/intent-input-change.html)와
132
+ [3건의 검증 결과·재현 명령](./docs/real-world-evaluation.md)을 볼 수 있습니다. 저장소를 clone한
133
+ 뒤 HTML 파일을 브라우저에서 열어 주세요. GitHub 파일 화면은 렌더링 대신 소스를 보여줄 수
134
+ 있습니다.
135
+
130
136
  ## 현재 구현된 기능
131
137
 
132
138
  현재 소스는 Git 변경사항 수집, 루트·npm workspace `package.json`의 직접 dependency와 npm lockfile 분석, TypeScript
@@ -145,11 +151,14 @@ LOW 구현체가 하나뿐인 추상화 추가
145
151
  - 외부 CDN이나 JavaScript dependency가 필요 없는 인라인 CSS·SVG 시각화
146
152
  - production·development dependency 추가 탐지
147
153
  - dependency 삭제, 버전 변경, 섹션 이동 탐지
154
+ - 새 직접 dependency에 정적 JS/TS 참조가 없으면 `low` 심각도의 검토 후보로 표시
148
155
  - 잘못된 `package.json`을 예외 대신 근거가 포함된 finding으로 보고
149
156
  - npm `package-lock.json` v2/v3의 실제 설치 패키지 추가·삭제·버전 변경 비교
150
157
  - scoped·중첩 설치 경로를 구분하고 로컬 workspace 링크는 제외
158
+ - pnpm `pnpm-lock.yaml` v9의 레지스트리 패키지 추가·삭제·버전 변경 비교(2개 문서 형식 포함)
151
159
  - 잘못되었거나 미지원인 lockfile을 누락하지 않고 finding으로 보고
152
160
  - 루트 `workspaces` 패턴에 속한 변경 manifest의 직접 dependency를 workspace별로 보고
161
+ - `pnpm-workspace.yaml`의 포함·제외 패턴에 속한 변경 manifest의 직접 dependency를 보고
153
162
  - workspace 설정 변경과 manifest의 workspace 안팎 이동을 탐지
154
163
  - finding 심각도(`high`, `medium`, `low`) 집계
155
164
  - CI 품질 게이트를 위한 `--fail-on` 종료 코드
@@ -172,6 +181,7 @@ LOW 구현체가 하나뿐인 추상화 추가
172
181
  - 해결하지 못한 상대 import와 읽기·파싱 실패를 분석 근거로 보존
173
182
  - working tree의 tracked·untracked 파일 또는 지정한 head ref를 동일한 결과점에서 분석
174
183
  - `.intentpatch.json`에 요청 의도, 예상 경로, 허용 경로와 변경량 예산 선언
184
+ - CLI 요청 문서 또는 선택적으로 GitHub PR 본문에서 요청 의도를 입력
175
185
  - 예상·허용 패턴을 벗어난 변경 파일을 파일별 `medium` finding으로 탐지
176
186
  - 변경 파일 수와 측정 라인 예산 초과를 수치 근거가 있는 `low` finding으로 탐지
177
187
  - Contract가 지정한 소스·테스트 경로를 분류하고 파일명 기준으로 관련 변경 연결
@@ -226,6 +236,16 @@ HTML 파일에는 스타일과 dependency 영향 SVG 그래프가 모두 포함
226
236
  IntentPatch를 실행한 현재 디렉터리를 기준으로 해석합니다. 기존 `--json`은
227
237
  `--format json`의 단축 옵션입니다.
228
238
 
239
+ 계약 파일 없이 원래 요청을 보고서에 담으려면 분석할 저장소 안에 텍스트·Markdown 파일을 저장하고 실행합니다.
240
+
241
+ ```bash
242
+ intentpatch analyze --intent-file request.md --format html --output report.html
243
+ ```
244
+
245
+ `--intent-file`은 계약의 `intent`만 덮어쓰며 기존 scope·테스트 정책은 유지합니다.
246
+ 요청 파일은 저장소 안의 일반 파일이어야 하고 64 KiB 이하여야 합니다. 요청 문장만으로
247
+ 예상 경로를 추측하거나 범위 검사를 활성화하지 않습니다.
248
+
229
249
  ### Change Contract로 요청 범위 검사
230
250
 
231
251
  분석할 저장소의 `.intentpatch.json`에 이번 요청의 기대 범위를 선언할 수 있습니다.
@@ -425,13 +445,17 @@ npm provenance가 자동 생성됩니다. 아직 npm에 존재하지 않는 신
425
445
  6. lockfile과 workspace를 고려한 package manager adapter
426
446
  - ✅ npm `package-lock.json` v2/v3의 설치 패키지 변경
427
447
  - ✅ npm workspace manifest의 직접 dependency 변경
428
- - pnpm·Yarn adapter
448
+ - ✅ pnpm `pnpm-lock.yaml` v9의 레지스트리 패키지 변경
449
+ - ✅ pnpm workspace manifest의 직접 dependency 변경
450
+ - Yarn adapter
429
451
  7. ✅ 직접 export된 공개 심볼 삭제와 export 해제 탐지
430
452
  8. ✅ 단일 HTML 대시보드와 SVG 기반 dependency 영향 그래프
431
453
  9. ✅ re-export·함수/인터페이스 호환성과 기존 코드 중복 가능성 탐지
432
454
  10. ✅ 구현체가 하나뿐인 신규 인터페이스 탐지
433
455
  11. ✅ PR·push 비교, Job Summary와 artifact 출력을 제공하는 GitHub Action
434
- 12. Codex·Claude Code·Cursor adapter
456
+ 12. 요청 입력과 에이전트 adapter
457
+ - ✅ CLI 요청 문서와 선택적 GitHub PR 본문 입력
458
+ - Codex·Claude Code·Cursor 전용 adapter
435
459
  13. 근거 기반 결과에 대한 선택적 LLM 설명
436
460
 
437
461
  ## 현재 제한사항
@@ -439,14 +463,24 @@ npm provenance가 자동 생성됩니다. 아직 npm에 존재하지 않는 신
439
463
  - 분석 대상은 최소 한 번 이상 커밋된 Git 저장소여야 합니다.
440
464
  - untracked symbolic link는 안전을 위해 내용을 읽지 않습니다.
441
465
  - 10 MiB를 초과하는 untracked 파일은 라인 수를 측정하지 않습니다.
442
- - 직접 dependency 선언 분석은 저장소 루트와 변경된 npm workspace `package.json`의
466
+ - 직접 dependency 선언 분석은 저장소 루트와 변경된 npm·pnpm workspace `package.json`의
443
467
  `dependencies`와 `devDependencies`를 대상으로 합니다.
468
+ - 정적 참조 없음 finding은 미사용 확정이 아닌 검토 후보입니다. 유지보수 대상 JS/TS
469
+ 소스의 명시적 import·re-export·문자열 `require()`·`import()`를 살펴봅니다. CLI나 설정
470
+ 파일에서만 사용하는 경우는 놓칠 수 있습니다. 파일 읽기·파싱이 불완전하거나 계산된 module
471
+ load가 있거나, 스캔한 소스가 없거나, 소스 파일이 5,000개를 넘으면 후보를 보고하지 않습니다.
444
472
  - npm `package-lock.json` v2/v3은 설치 경로와 버전을 비교합니다. 부모 dependency 귀속,
445
473
  integrity hash나 취약점 정보까지 분석하지는 않습니다.
474
+ - pnpm `pnpm-lock.yaml` v9은 프로젝트 문서의 레지스트리 패키지 ID와 버전을 비교합니다.
475
+ integrity만 바뀐 경우, 로컬·Git 패키지, snapshot의 peer 변형, 부모 dependency 귀속은 분석하지 않습니다.
476
+ 루트의 직접 dependency 여부는 루트 importer를 기준으로 표시합니다.
446
477
  - workspace 판별은 루트의 npm `workspaces` 배열과 명시 경로, `*`·`**`·`?` 패턴을 지원합니다.
447
478
  부정·중괄호·문자 클래스 패턴은 미지원 finding으로 보고합니다.
448
- - pnpm·Yarn lockfile, 코드에서의 실제 dependency 사용 여부는 아직 분석하지 않습니다.
449
- - working tree의 `package-lock.json`은 10 MiB, 그 외 텍스트 snapshot은 1 MiB로 제한합니다.
479
+ - pnpm workspace는 `pnpm-workspace.yaml`의 `packages`에 명시한 `*`·`**`·`?`와 선행 `!`
480
+ 제외 패턴을 지원합니다. npm 설정이 함께 있으면 중복 보고를 막기 위해 pnpm 설정을
481
+ 우선합니다. 그 외 glob 문법과 catalog는 해석하지 않습니다.
482
+ - Yarn lockfile과 런타임에서의 실제 dependency 사용 여부는 아직 분석하지 않습니다.
483
+ - working tree의 `package-lock.json`·`pnpm-lock.yaml`은 10 MiB, 그 외 텍스트 snapshot은 1 MiB로 제한합니다.
450
484
  - 심볼 분석은 `.ts`와 `.tsx`의 이름이 있는 최상위 함수, 클래스, 인터페이스, 타입
451
485
  별칭만 지원합니다.
452
486
  - 공개 API 분석은 이름이 있는 최상위 함수·인터페이스, 로컬 `export { name }`, 외부
package/README.md CHANGED
@@ -18,7 +18,7 @@ IntentPatch combines **Git diff analysis, static analysis, and dependency analys
18
18
 
19
19
  ## Quick start
20
20
 
21
- IntentPatch requires Node.js 20 or later and Git. Run the published v0.2.0 CLI without
21
+ IntentPatch requires Node.js 20 or later and Git. Run the published v0.3.0 CLI without
22
22
  installing it globally:
23
23
 
24
24
  ```bash
@@ -62,7 +62,7 @@ jobs:
62
62
 
63
63
  - name: Analyze pull request
64
64
  id: intentpatch
65
- uses: xx2xxjaeil/intent-patch@v0.2.0
65
+ uses: xx2xxjaeil/intent-patch@v0.3.0
66
66
  with:
67
67
  fail-on: high
68
68
 
@@ -74,8 +74,9 @@ jobs:
74
74
  path: intentpatch-report
75
75
  ```
76
76
 
77
- Pin the action to a released version or an immutable commit SHA. The v0.2.0 release includes
78
- TypeScript path aliases and npm lockfile/workspace analysis; `@main` follows unreleased changes.
77
+ Pin the action to a released version or an immutable commit SHA. The v0.3.0 release adds pnpm
78
+ lockfile/workspace analysis, static dependency-use review, and explicit request input; `@main`
79
+ follows unreleased changes.
79
80
 
80
81
  The action detects the comparison range for pull request and push events and produces:
81
82
 
@@ -121,6 +122,11 @@ LOW New abstraction has only one implementation
121
122
 
122
123
  Every finding includes the relevant file, a stable rule ID, and evidence for the decision instead of only presenting an unexplained warning.
123
124
 
125
+ For a report generated from an actual IntentPatch commit, see the
126
+ [standalone HTML example](./docs/examples/intent-input-change.html) and the
127
+ [three-case evaluation with reproduction commands](./docs/real-world-evaluation.md). After cloning,
128
+ open the HTML file locally in a browser; GitHub may show its source rather than render it.
129
+
124
130
  ## Implemented capabilities
125
131
 
126
132
  The current source tree analyzes Git changes, direct dependencies in the root `package.json`, top-level TypeScript symbols and public API changes, possible duplicate implementations, single-implementation abstractions, import-graph impact, and related test changes.
@@ -144,11 +150,14 @@ The current source tree analyzes Git changes, direct dependencies in the root `p
144
150
 
145
151
  - Detect additions to production and development dependencies.
146
152
  - Detect dependency removal, version changes, and section moves.
153
+ - Flag a newly added direct dependency with no static JS/TS import as a low-severity review candidate.
147
154
  - Report malformed `package.json` files as evidence-backed findings instead of crashing.
148
155
  - Compare resolved package additions, removals, and version changes in npm `package-lock.json` v2/v3.
149
156
  - Keep scoped and nested installation paths distinct, and exclude local workspace links.
157
+ - Compare resolved registry package changes in pnpm `pnpm-lock.yaml` v9, including two-document lockfiles.
150
158
  - Report malformed or unsupported lockfiles as findings rather than silently skipping them.
151
159
  - Attribute direct dependency changes to changed npm workspace manifests selected by the root `workspaces` patterns.
160
+ - Analyze changed pnpm workspace manifests selected by `pnpm-workspace.yaml`, including exclusion patterns.
152
161
  - Report changes to workspace patterns and manifest moves into or out of a configured workspace.
153
162
  - Extract top-level named functions, classes, interfaces, and type aliases from `.ts` and `.tsx` files.
154
163
  - Detect symbol additions, modifications, and removals with source locations.
@@ -171,6 +180,7 @@ The current source tree analyzes Git changes, direct dependencies in the root `p
171
180
  - Preserve unresolved relative imports and file read or parse failures as evidence.
172
181
  - Build the graph at the same result point as the diff: the working tree or the selected head ref.
173
182
  - Read intent, expected paths, allowed paths, and change budgets from `.intentpatch.json`.
183
+ - Accept a request text/Markdown file through the CLI, or opt in to using the PR body in the GitHub Action.
174
184
  - Report each file outside expected and allowed patterns as a medium-severity finding.
175
185
  - Report file-count and measurable-line budget overruns with numeric evidence.
176
186
  - Classify source and test paths declared by the contract and connect related changes by basename.
@@ -219,6 +229,14 @@ node dist/presentation/cli/main.js analyze \
219
229
 
220
230
  The HTML file contains all styles and the dependency-impact SVG, so it opens directly without a server or API key. `--output` also works with text and JSON formats. Relative output paths are resolved from the directory where IntentPatch is executed. `--json` is an alias for `--format json`.
221
231
 
232
+ To include the original request without writing a contract, save it in the analyzed repository and run:
233
+
234
+ ```bash
235
+ intentpatch analyze --intent-file request.md --format html --output report.html
236
+ ```
237
+
238
+ `--intent-file` overrides only the contract's `intent`; existing scope and test policies remain intact. The file must be a regular file inside the analyzed repository and at most 64 KiB. Request text alone does not infer expected paths or activate scope checks.
239
+
222
240
  ### Check request scope with a Change Contract
223
241
 
224
242
  Create `.intentpatch.json` in the repository being analyzed and declare the expected scope of the request:
@@ -411,13 +429,17 @@ No long-lived npm token is stored as a GitHub secret. Public packages published
411
429
  6. Package-manager adapters for lockfiles and workspaces
412
430
  - ✅ npm `package-lock.json` v2/v3 resolved package changes
413
431
  - ✅ npm workspace manifest dependency changes
414
- - pnpm and Yarn adapters
432
+ - ✅ pnpm `pnpm-lock.yaml` v9 resolved registry package changes
433
+ - ✅ pnpm workspace manifest dependency changes
434
+ - Yarn adapter
415
435
  7. ✅ Detection of removed public exports
416
436
  8. ✅ Standalone HTML dashboard and SVG dependency-impact graph
417
437
  9. ✅ Re-export and function/interface compatibility checks plus possible code duplication
418
438
  10. ✅ Detection of newly introduced single-implementation interfaces
419
439
  11. ✅ GitHub Action with PR/push comparison, Job Summary, annotations, and artifacts
420
- 12. Codex, Claude Code, and Cursor adapters
440
+ 12. Request capture and agent adapters
441
+ - ✅ CLI request file and opt-in GitHub PR body
442
+ - Codex, Claude Code, and Cursor-specific adapters
421
443
  13. Optional LLM explanations grounded in deterministic evidence
422
444
 
423
445
  ## Current limitations
@@ -425,11 +447,14 @@ No long-lived npm token is stored as a GitHub secret. Public packages published
425
447
  - The target must be a Git repository with at least one commit.
426
448
  - Untracked symbolic links are not read for safety.
427
449
  - Line counts are skipped for untracked files larger than 10 MiB.
428
- - Direct dependency declarations are analyzed from `dependencies` and `devDependencies` in the root npm `package.json` and changed npm workspace manifests.
450
+ - Direct dependency declarations are analyzed from `dependencies` and `devDependencies` in the root `package.json` and changed npm/pnpm workspace manifests.
451
+ - The no-static-reference finding is a review candidate, not proof that a package is unused. It checks explicit JS/TS imports, re-exports, literal `require()` and `import()` across maintained source files; CLI-only/configuration usage may not appear. It does not emit a candidate if source reads or parsing are incomplete, a computed module load exists, no source was scanned, or more than 5,000 source files are present.
429
452
  - npm `package-lock.json` v2/v3 analysis compares installed package paths and versions, not dependency provenance, integrity hashes, or vulnerability data. It does not attribute transitive packages to their parents.
453
+ - pnpm `pnpm-lock.yaml` v9 analysis compares registry package IDs and versions in the project document. It ignores integrity-only edits, local/Git packages, snapshot peer variants, and dependency provenance. Root-direct evidence comes from the root importer only.
430
454
  - Workspace detection supports the root npm `workspaces` array with explicit paths and `*`, `**`, and `?` globs. Negation, brace, and character-class patterns are reported as unsupported.
431
- - pnpm and Yarn lockfiles and real dependency usage in source code are not analyzed yet.
432
- - Working-tree `package-lock.json` files are limited to 10 MiB; other text snapshots retain the 1 MiB limit.
455
+ - pnpm workspace detection reads `pnpm-workspace.yaml` `packages` patterns with `*`, `**`, `?`, and leading `!` exclusions. When both npm and pnpm workspace settings exist, pnpm settings take precedence to avoid duplicate findings. Other glob features and pnpm catalogs are not interpreted.
456
+ - Yarn lockfiles and runtime dependency usage are not analyzed yet.
457
+ - Working-tree `package-lock.json` and `pnpm-lock.yaml` files are limited to 10 MiB; other text snapshots retain the 1 MiB limit.
433
458
  - Symbol analysis supports named top-level functions, classes, interfaces, and type aliases in `.ts` and `.tsx` files.
434
459
  - Public API analysis supports named top-level functions and interfaces, local `export { name }`, external `export { name } from`, and `export * from`. Package `exports`, anonymous default exports, and detailed class or type-alias contracts are not interpreted yet.
435
460
  - Function compatibility compares explicitly written parameter and return-type text. It does not evaluate inferred return types or full TypeScript structural assignability.
@@ -1,6 +1,7 @@
1
1
  export type ModuleReferenceExtractionResult = Readonly<{
2
2
  kind: "success";
3
3
  specifiers: readonly string[];
4
+ hasDynamicSpecifier?: boolean;
4
5
  }> | Readonly<{
5
6
  kind: "unavailable";
6
7
  reason: string;
@@ -1 +1 @@
1
- {"version":3,"file":"module-reference-extractor.d.ts","sourceRoot":"","sources":["../../../src/application/ports/module-reference-extractor.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,+BAA+B,GACvC,QAAQ,CAAC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC,GAC5D,QAAQ,CAAC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEtD,oDAAoD;AACpD,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,+BAA+B,CAAC;CACxE"}
1
+ {"version":3,"file":"module-reference-extractor.d.ts","sourceRoot":"","sources":["../../../src/application/ports/module-reference-extractor.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,+BAA+B,GACvC,QAAQ,CAAC;IACP,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B,CAAC,GACF,QAAQ,CAAC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEtD,oDAAoD;AACpD,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,+BAA+B,CAAC;CACxE"}
@@ -0,0 +1,7 @@
1
+ /** 여러 package-manager 파서에서 같은 실패 형태를 사용한다. */
2
+ export declare function invalidParseResult(reason: string): Readonly<{
3
+ ok: false;
4
+ kind: "invalid";
5
+ reason: string;
6
+ }>;
7
+ //# sourceMappingURL=parse-failure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-failure.d.ts","sourceRoot":"","sources":["../../../src/application/ports/parse-failure.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,GACb,QAAQ,CAAC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAE1D"}
@@ -0,0 +1,5 @@
1
+ /** 여러 package-manager 파서에서 같은 실패 형태를 사용한다. */
2
+ export function invalidParseResult(reason) {
3
+ return Object.freeze({ ok: false, kind: "invalid", reason });
4
+ }
5
+ //# sourceMappingURL=parse-failure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-failure.js","sourceRoot":"","sources":["../../../src/application/ports/parse-failure.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,MAAM,UAAU,kBAAkB,CAChC,MAAc;IAEd,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,20 @@
1
+ /** pnpm v9 lockfile의 프로젝트 패키지 목록에서 비교할 사실이다. */
2
+ export interface PnpmLockedPackage {
3
+ readonly id: string;
4
+ readonly name: string;
5
+ readonly version: string;
6
+ readonly rootDirect: boolean;
7
+ }
8
+ export type PnpmLockParseResult = Readonly<{
9
+ ok: true;
10
+ packages: ReadonlyMap<string, PnpmLockedPackage>;
11
+ }> | Readonly<{
12
+ ok: false;
13
+ kind: "invalid" | "unsupported";
14
+ reason: string;
15
+ }>;
16
+ /** YAML 파일 형식 해석을 분석 규칙에서 분리하는 입력 포트다. */
17
+ export interface PnpmLockParser {
18
+ parse(content: string): PnpmLockParseResult;
19
+ }
20
+ //# sourceMappingURL=pnpm-lock-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pnpm-lock-parser.d.ts","sourceRoot":"","sources":["../../../src/application/ports/pnpm-lock-parser.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,MAAM,mBAAmB,GAC3B,QAAQ,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;CAAE,CAAC,GACxE,QAAQ,CAAC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,SAAS,GAAG,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE7E,0CAA0C;AAC1C,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,CAAC;CAC7C"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pnpm-lock-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pnpm-lock-parser.js","sourceRoot":"","sources":["../../../src/application/ports/pnpm-lock-parser.ts"],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ import type { WorkspacePatterns } from "../services/workspace-manifest-analysis.js";
2
+ export type PnpmWorkspaceParseResult = Readonly<{
3
+ ok: true;
4
+ patterns: WorkspacePatterns;
5
+ }> | Readonly<{
6
+ ok: false;
7
+ kind: "invalid" | "unsupported";
8
+ reason: string;
9
+ }>;
10
+ /** pnpm 설정 파일을 workspace glob 사실로 바꾸는 출력 포트다. */
11
+ export interface PnpmWorkspaceParser {
12
+ parse(content: string | undefined): PnpmWorkspaceParseResult;
13
+ }
14
+ //# sourceMappingURL=pnpm-workspace-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pnpm-workspace-parser.d.ts","sourceRoot":"","sources":["../../../src/application/ports/pnpm-workspace-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAEpF,MAAM,MAAM,wBAAwB,GAChC,QAAQ,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,iBAAiB,CAAA;CAAE,CAAC,GACnD,QAAQ,CAAC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,SAAS,GAAG,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE7E,iDAAiD;AACjD,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,wBAAwB,CAAC;CAC9D"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pnpm-workspace-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pnpm-workspace-parser.js","sourceRoot":"","sources":["../../../src/application/ports/pnpm-workspace-parser.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ import type { Finding } from "../../domain/finding.js";
2
+ import type { AnalysisContext, AnalysisRule } from "../ports/analysis-rule.js";
3
+ import type { FileSnapshotSource } from "../ports/file-snapshot-source.js";
4
+ import type { ModuleReferenceExtractor } from "../ports/module-reference-extractor.js";
5
+ import type { PnpmWorkspaceParser } from "../ports/pnpm-workspace-parser.js";
6
+ import type { ProjectFileSource } from "../ports/project-file-source.js";
7
+ /** 새 직접 dependency의 정적 소스 참조가 없을 때만 검토 후보를 제시한다. */
8
+ export declare class AddedDependencyUsageRule implements AnalysisRule {
9
+ private readonly snapshots;
10
+ private readonly files;
11
+ private readonly extractor;
12
+ private readonly pnpmWorkspaceParser;
13
+ constructor(snapshots: FileSnapshotSource, files: ProjectFileSource, extractor: ModuleReferenceExtractor, pnpmWorkspaceParser: PnpmWorkspaceParser);
14
+ analyze(context: AnalysisContext): Promise<readonly Finding[]>;
15
+ }
16
+ //# sourceMappingURL=added-dependency-usage-rule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"added-dependency-usage-rule.d.ts","sourceRoot":"","sources":["../../../src/application/rules/added-dependency-usage-rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AACvF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAgBzE,oDAAoD;AACpD,qBAAa,wBAAyB,YAAW,YAAY;IAEzD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,mBAAmB;gBAHnB,SAAS,EAAE,kBAAkB,EAC7B,KAAK,EAAE,iBAAiB,EACxB,SAAS,EAAE,wBAAwB,EACnC,mBAAmB,EAAE,mBAAmB;IAG9C,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,OAAO,EAAE,CAAC;CAoE5E"}
@@ -0,0 +1,98 @@
1
+ import { NpmWorkspaceDependencyRule } from "./npm-workspace-dependency-rule.js";
2
+ import { PackageDependencyRule } from "./package-dependency-rule.js";
3
+ import { PnpmWorkspaceDependencyRule } from "./pnpm-workspace-dependency-rule.js";
4
+ const rootManifest = "package.json";
5
+ const generatedDirectories = new Set([
6
+ "node_modules",
7
+ "dist",
8
+ "build",
9
+ "coverage",
10
+ "action-dist",
11
+ ".next",
12
+ ".turbo",
13
+ ]);
14
+ /** 새 직접 dependency의 정적 소스 참조가 없을 때만 검토 후보를 제시한다. */
15
+ export class AddedDependencyUsageRule {
16
+ snapshots;
17
+ files;
18
+ extractor;
19
+ pnpmWorkspaceParser;
20
+ constructor(snapshots, files, extractor, pnpmWorkspaceParser) {
21
+ this.snapshots = snapshots;
22
+ this.files = files;
23
+ this.extractor = extractor;
24
+ this.pnpmWorkspaceParser = pnpmWorkspaceParser;
25
+ }
26
+ async analyze(context) {
27
+ const manifestFindings = (await Promise.all([
28
+ new PackageDependencyRule(this.snapshots, rootManifest).analyze(context),
29
+ new NpmWorkspaceDependencyRule(this.snapshots).analyze(context),
30
+ new PnpmWorkspaceDependencyRule(this.snapshots, this.pnpmWorkspaceParser).analyze(context),
31
+ ])).flat();
32
+ const added = manifestFindings.filter((finding) => finding.ruleId === "dependency/new-production" ||
33
+ finding.ruleId === "dependency/new-development");
34
+ if (added.length === 0)
35
+ return [];
36
+ const paths = (await this.files.listPaths(context.target)).filter((path) => this.extractor.supports(path) &&
37
+ !path.split("/").some((part) => generatedDirectories.has(part)));
38
+ const referenced = new Set();
39
+ if (paths.length === 0 || paths.length > 5_000)
40
+ return [];
41
+ let complete = true;
42
+ // 읽기·파싱 실패나 계산할 수 없는 동적 import가 있으면 미사용 후보를 단정하지 않는다.
43
+ for (const path of paths) {
44
+ const file = await this.files.read(context.target, path);
45
+ if (file.kind !== "success") {
46
+ complete = false;
47
+ break;
48
+ }
49
+ const references = this.extractor.extract(path, file.content);
50
+ if (references.kind !== "success" || references.hasDynamicSpecifier === true) {
51
+ complete = false;
52
+ break;
53
+ }
54
+ for (const specifier of references.specifiers) {
55
+ const packageName = packageNameFromSpecifier(specifier);
56
+ if (packageName !== undefined)
57
+ referenced.add(packageName);
58
+ }
59
+ }
60
+ if (!complete)
61
+ return [];
62
+ return added.flatMap((finding) => {
63
+ const name = finding.evidence.package;
64
+ if (typeof name !== "string" || referenced.has(name))
65
+ return [];
66
+ return [
67
+ {
68
+ ruleId: "dependency/no-static-reference",
69
+ severity: "low",
70
+ title: "New dependency has no static source reference",
71
+ description: `${name} was added to ${finding.file}, but no static JS/TS import was found. Check CLI, configuration, and generated-code usage before removing it.`,
72
+ file: finding.file,
73
+ evidence: {
74
+ package: name,
75
+ section: String(finding.evidence.section),
76
+ scannedFiles: paths.length,
77
+ ...(finding.evidence.workspace === undefined
78
+ ? {}
79
+ : { workspace: finding.evidence.workspace }),
80
+ ...(finding.evidence.packageManager === undefined
81
+ ? {}
82
+ : { packageManager: finding.evidence.packageManager }),
83
+ },
84
+ },
85
+ ];
86
+ });
87
+ }
88
+ }
89
+ function packageNameFromSpecifier(specifier) {
90
+ if (specifier.startsWith(".") ||
91
+ specifier.startsWith("/") ||
92
+ specifier.startsWith("#") ||
93
+ specifier.startsWith("node:"))
94
+ return undefined;
95
+ const parts = specifier.split("/");
96
+ return specifier.startsWith("@") && parts.length >= 2 ? `${parts[0]}/${parts[1]}` : parts[0];
97
+ }
98
+ //# sourceMappingURL=added-dependency-usage-rule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"added-dependency-usage-rule.js","sourceRoot":"","sources":["../../../src/application/rules/added-dependency-usage-rule.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"npm-workspace-dependency-rule.d.ts","sourceRoot":"","sources":["../../../src/application/rules/npm-workspace-dependency-rule.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAW3E,qEAAqE;AACrE,qBAAa,0BAA2B,YAAW,YAAY;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,kBAAkB;IAEpD,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,OAAO,EAAE,CAAC;CAwF5E"}
1
+ {"version":3,"file":"npm-workspace-dependency-rule.d.ts","sourceRoot":"","sources":["../../../src/application/rules/npm-workspace-dependency-rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAY3E,qEAAqE;AACrE,qBAAa,0BAA2B,YAAW,YAAY;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,kBAAkB;IAEpD,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,OAAO,EAAE,CAAC;CAsD5E"}
@@ -1,7 +1,6 @@
1
- import { matchesPathPattern } from "../services/path-pattern.js";
2
- import { PackageDependencyRule } from "./package-dependency-rule.js";
1
+ import { isRecord } from "../../domain/value-guards.js";
2
+ import { analyzeWorkspaceManifests, isNestedManifestChange, } from "../services/workspace-manifest-analysis.js";
3
3
  const rootManifestPath = "package.json";
4
- const manifestSuffix = "/package.json";
5
4
  /** npm workspaces에 속한 변경 manifest를 찾아 기존 직접 dependency 규칙으로 분석한다. */
6
5
  export class NpmWorkspaceDependencyRule {
7
6
  snapshots;
@@ -14,6 +13,10 @@ export class NpmWorkspaceDependencyRule {
14
13
  if (manifestChanges.length === 0 && !rootChanged) {
15
14
  return [];
16
15
  }
16
+ // pnpm-workspace.yaml이 있으면 pnpm 설정이 우선한다. 동일 manifest의 finding 중복을 피한다.
17
+ const pnpmConfig = await this.snapshots.read(context.target, "pnpm-workspace.yaml");
18
+ if (pnpmConfig.before !== undefined || pnpmConfig.after !== undefined)
19
+ return [];
17
20
  const snapshot = await this.snapshots.read(context.target, rootManifestPath);
18
21
  const before = parseWorkspaceConfig(snapshot.before);
19
22
  const after = parseWorkspaceConfig(snapshot.after);
@@ -41,59 +44,11 @@ export class NpmWorkspaceDependencyRule {
41
44
  },
42
45
  });
43
46
  }
44
- const results = await Promise.all(manifestChanges.map(async (change) => {
45
- const previousPath = change.kind === "renamed" ? (change.previousPath ?? change.path) : change.path;
46
- const currentPath = change.path;
47
- const wasWorkspace = change.kind !== "added" &&
48
- change.kind !== "copied" &&
49
- isConfiguredWorkspace(previousPath, before.patterns);
50
- const isWorkspace = change.kind !== "deleted" && isConfiguredWorkspace(currentPath, after.patterns);
51
- if (!wasWorkspace && !isWorkspace) {
52
- return [];
53
- }
54
- const manifestPath = isNestedManifestPath(currentPath) ? currentPath : previousPath;
55
- const workspacePath = manifestPath.slice(0, -manifestSuffix.length);
56
- const membershipFinding = change.kind === "renamed" && wasWorkspace !== isWorkspace
57
- ? [
58
- {
59
- ruleId: "dependency/workspace-membership-changed",
60
- severity: "low",
61
- title: "npm workspace membership changed",
62
- description: `${previousPath} moved to ${currentPath}, changing workspace membership.`,
63
- file: currentPath,
64
- evidence: {
65
- previousPath,
66
- currentPath,
67
- fromWorkspace: wasWorkspace,
68
- toWorkspace: isWorkspace,
69
- },
70
- },
71
- ]
72
- : [];
73
- const dependencyFindings = await new PackageDependencyRule(this.snapshots, manifestPath).analyze(context);
74
- return [
75
- ...membershipFinding,
76
- ...dependencyFindings.map((finding) => ({
77
- ...finding,
78
- evidence: { ...finding.evidence, workspace: workspacePath },
79
- })),
80
- ];
81
- }));
82
- return [...findings, ...results.flat()];
83
- }
84
- }
85
- function isNestedManifestChange(change) {
86
- return isNestedManifestPath(change.path) || isNestedManifestPath(change.previousPath);
87
- }
88
- function isNestedManifestPath(path) {
89
- return path?.endsWith(manifestSuffix) === true;
90
- }
91
- function isConfiguredWorkspace(path, patterns) {
92
- if (!isNestedManifestPath(path)) {
93
- return false;
47
+ return [
48
+ ...findings,
49
+ ...(await analyzeWorkspaceManifests(context, this.snapshots, manifestChanges, { includes: before.patterns, excludes: [] }, { includes: after.patterns, excludes: [] }, "npm")),
50
+ ];
94
51
  }
95
- const directory = path.slice(0, -manifestSuffix.length);
96
- return patterns.some((pattern) => matchesPathPattern(directory, pattern));
97
52
  }
98
53
  function parseWorkspaceConfig(content) {
99
54
  if (content === undefined) {
@@ -149,7 +104,4 @@ function configFinding(side, result) {
149
104
  evidence: { side, reason: result.reason },
150
105
  };
151
106
  }
152
- function isRecord(value) {
153
- return typeof value === "object" && value !== null && !Array.isArray(value);
154
- }
155
107
  //# sourceMappingURL=npm-workspace-dependency-rule.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"npm-workspace-dependency-rule.js","sourceRoot":"","sources":["../../../src/application/rules/npm-workspace-dependency-rule.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"npm-workspace-dependency-rule.js","sourceRoot":"","sources":["../../../src/application/rules/npm-workspace-dependency-rule.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"package-dependency-rule.d.ts","sourceRoot":"","sources":["../../../src/application/rules/package-dependency-rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAY,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAgB3E;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,YAAY;IAEtD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;gBADZ,SAAS,EAAE,kBAAkB,EAC7B,YAAY,SAAmB;IAGrC,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,OAAO,EAAE,CAAC;CA6B5E"}
1
+ {"version":3,"file":"package-dependency-rule.d.ts","sourceRoot":"","sources":["../../../src/application/rules/package-dependency-rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAY,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAgB3E;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,YAAY;IAEtD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;gBADZ,SAAS,EAAE,kBAAkB,EAC7B,YAAY,SAAmB;IAGrC,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,OAAO,EAAE,CAAC;CA6B5E"}
@@ -1,3 +1,4 @@
1
+ import { isRecord } from "../../domain/value-guards.js";
1
2
  const rootManifestPath = "package.json";
2
3
  const dependencySections = ["dependencies", "devDependencies"];
3
4
  /**
@@ -173,7 +174,4 @@ function invalidManifest(side, reason, manifestPath) {
173
174
  function severityFor(section) {
174
175
  return section === "dependencies" ? "medium" : "low";
175
176
  }
176
- function isRecord(value) {
177
- return typeof value === "object" && value !== null && !Array.isArray(value);
178
- }
179
177
  //# sourceMappingURL=package-dependency-rule.js.map