Skip to content

fix: stabilize CLI diagnostic codes - #1109

Merged
kang-heewon merged 1 commit into
trunkfrom
fix/971-stable-cli-diagnostic-codes
Jun 30, 2026
Merged

fix: stabilize CLI diagnostic codes#1109
kang-heewon merged 1 commit into
trunkfrom
fix/971-stable-cli-diagnostic-codes

Conversation

@kang-heewon

@kang-heewon kang-heewon commented Jun 29, 2026

Copy link
Copy Markdown
Member

Summary

  • CLI-produced doctor, ops/jobs, DI check, project map, and generated usage-dashboard diagnostics now emit registered CROCO_* codes.
  • Previous slash-form identifiers are preserved as explicit legacyCode metadata and documented in the troubleshooting migration table.
  • The generated Problem registry/cookbook now resolves imported code constants so stable CLI ops/jobs Problem codes remain indexed.

Validation

  • CI=true corepack pnpm --filter @croco/cli --filter @croco/diagnostics-core test
  • CI=true corepack pnpm --filter @croco/cli --filter @croco/diagnostics-core typecheck
  • CI=true corepack pnpm exec vitest run scripts/tests/problem-registry.spec.ts scripts/tests/strict-contract-typecheck.spec.ts --config vitest.config.ts
  • CI=true corepack pnpm check
  • CI=true corepack pnpm --filter @croco/cli... build
  • Static scan: no primary slash-form CLI diagnostic codes
  • Generated Problem registry includes all 6 stable CLI ops/jobs Problem codes

Fixes #971

Summary by CodeRabbit

  • New Features
    • CLI 진단/Problem이 primary CROCO_* 코드로 출력되며, 기존 표기들은 legacyCode 별칭으로 함께 제공됩니다(Doctor/DI Check/Jobs/Ops/Project Map/Usage Dashboard 및 JSON 출력 포함).
    • CLI 코드 체계가 통합되며, 일부 신규 CROCO_CLI_* 코드가 레지스트리에 추가되었습니다.
  • Bug Fixes
    • 진단 코드 정규화/폴백(unknown 포함) 및 JSON 직렬화가 안정화되었습니다.
    • Jobs “unavailable” 케이스의 상태가 404 → 409로 조정되었습니다.
  • Documentation
    • “CLI diagnostic code migration” 가이드와 Problem Recovery Cookbook, 관련 API 타입 문서가 CROCO_*/legacyCode 기준으로 갱신되었습니다.

@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@kang-heewon, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 19 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

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

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

How do review limits work?

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

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 42ae7cc0-0a73-46a8-81a4-7e4d958cd0fe

📥 Commits

Reviewing files that changed from the base of the PR and between dddd5b2 and de74608.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (31)
  • .changeset/stable-cli-diagnostic-codes.md
  • docs/problem-code-registry.json
  • docs/troubleshooting/diagnostics.md
  • packages/cli/package.json
  • packages/cli/src/commands/diCheck.ts
  • packages/cli/src/commands/doctor.ts
  • packages/cli/src/commands/generateUsageDashboard.ts
  • packages/cli/src/commands/jobs.ts
  • packages/cli/src/commands/projectMap.ts
  • packages/cli/src/libs/diagnosticCodes.ts
  • packages/cli/src/libs/ops.ts
  • packages/cli/src/tests/diCheck.spec.ts
  • packages/cli/src/tests/diagnosticCodes.spec.ts
  • packages/cli/src/tests/doctor.spec.ts
  • packages/cli/src/tests/generateUsageDashboard.spec.ts
  • packages/cli/src/tests/integration/e2e.spec.ts
  • packages/cli/src/tests/jobs.spec.ts
  • packages/cli/src/tests/opsStatus.spec.ts
  • packages/cli/src/tests/projectMap.spec.ts
  • packages/cli/vitest.config.ts
  • packages/diagnostics-core/src/libs/DiagnosticCodes.ts
  • packages/diagnostics-core/src/tests/DiagnosticCodes.spec.ts
  • packages/docs/scripts/sanitize-typedoc-index.mjs
  • packages/docs/src/content/docs/api/cli/src/type-aliases/DiCheckDiagnostic.md
  • packages/docs/src/content/docs/api/cli/src/type-aliases/DoctorDiagnostic.md
  • packages/docs/src/content/docs/api/diagnostics-core/src/type-aliases/DiagnosticCodeDefinition.md
  • packages/docs/src/content/docs/api/diagnostics-core/src/variables/CROCO_DIAGNOSTIC_CODE_DEFINITIONS.md
  • packages/docs/src/content/docs/en/reference/problem-recovery-cookbook.md
  • scripts/problem-registry.mts
  • scripts/strict-contract-typecheck.mts
  • scripts/tests/problem-registry.spec.ts
📝 Walkthrough

Walkthrough

CLI 진단 코드를 CROCO_* 안정 코드로 전환하고, legacy 식별자는 legacyCode로 보존합니다. diagnostics-core, CLI 생산자와 테스트, registry 수집기, 문서가 함께 갱신됩니다.

Changes

CLI 진단 코드 CROCO_* 마이그레이션

Layer / File(s) Summary
diagnostics-core: legacyCodes 및 CLI 코드 정의
packages/diagnostics-core/src/libs/DiagnosticCodes.ts, packages/diagnostics-core/src/tests/DiagnosticCodes.spec.ts
DiagnosticCodeDefinitionlegacyCodes를 추가하고, CLI 진단 정의 생성 헬퍼와 입력 타입을 도입합니다. CROCO_DIAGNOSTIC_CODE_DEFINITIONS의 CLI 항목을 헬퍼 기반으로 재구성하며, 테스트는 legacy 코드가 정의에 포함되고 진단 코드로는 취급되지 않는지 확인합니다.
CLI diagnosticCodes.ts 유틸과 패키지 설정
packages/cli/src/libs/diagnosticCodes.ts, packages/cli/package.json, packages/cli/vitest.config.ts
CLI_DIAGNOSTIC_CODESCLI_LEGACY_DIAGNOSTIC_CODES, 관련 타입, legacyCode 주입/조회 헬퍼를 추가합니다. @croco/diagnostics-core 의존성과 Vitest alias도 함께 추가됩니다.
doctor/jobs/ops/diCheck/projectMap/usage dashboard 생산자
packages/cli/src/commands/doctor.ts, packages/cli/src/commands/jobs.ts, packages/cli/src/libs/ops.ts, packages/cli/src/commands/diCheck.ts, packages/cli/src/commands/projectMap.ts, packages/cli/src/commands/generateUsageDashboard.ts, packages/cli/src/tests/integration/e2e.spec.ts
각 CLI 진단 생산자가 하드코딩된 slash-form 코드 대신 CROCO_* 상수와 legacyCode를 사용하도록 바뀌고, diCheck 정규화와 usage dashboard 직렬화도 함께 갱신됩니다.
CLI 테스트 갱신
packages/cli/src/tests/doctor.spec.ts, packages/cli/src/tests/jobs.spec.ts, packages/cli/src/tests/opsStatus.spec.ts, packages/cli/src/tests/diCheck.spec.ts, packages/cli/src/tests/projectMap.spec.ts, packages/cli/src/tests/generateUsageDashboard.spec.ts, packages/cli/src/tests/diagnosticCodes.spec.ts
CLI 테스트들이 stable code와 legacyCode 기대값으로 갱신되고, diCheck 정규화, projectMap 메타데이터, usage dashboard 직렬화, jobs/ops/doctor 출력, 진단 코드 금지 규칙을 검증합니다.
registry, docs, and troubleshooting updates
scripts/problem-registry.mts, scripts/strict-contract-typecheck.mts, scripts/tests/problem-registry.spec.ts, docs/problem-code-registry.json, docs/troubleshooting/diagnostics.md, .changeset/stable-cli-diagnostic-codes.md, packages/docs/src/content/docs/...
problem-registry와 관련 문서가 CROCO_* 코드, legacy alias, 상대 import 추적, cookbook/문서 API 갱신을 반영합니다.

추정 코드 리뷰 노력

🎯 4 (Complex) | ⏱️ ~60 minutes

관련 PR

  • croco-dev/framework#1041: packages/cli/src/commands/diCheck.ts의 진단 정규화 흐름과 테스트가 이번 변경의 diCheck stable/legacy 코드 처리와 직접 겹칩니다.
  • croco-dev/framework#833: packages/cli/src/libs/ops.ts 및 ops 관련 진단 코드/테스트 변경이 이번 PR의 ops 진단 마이그레이션과 연결됩니다.
  • croco-dev/framework#817: ops status 진단 출력 및 테스트 경로가 이번 PR의 opsStatus.spec.ts 갱신과 직접 관련됩니다.
🚥 Pre-merge checks | ✅ 4 | ❌ 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 (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 CLI 진단 코드 안정화라는 핵심 변경을 정확히 요약합니다.
Linked Issues check ✅ Passed doctor, jobs/ops, DI check, project map, usage-dashboard의 CROCO_* 전환과 문서·테스트 갱신이 요구사항과 일치합니다.
Out of Scope Changes check ✅ Passed 보이는 변경은 진단 코드 마이그레이션과 이를 뒷받침하는 테스트·문서·레지스트리 보강에 한정되어 있습니다.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/971-stable-cli-diagnostic-codes

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.

@github-actions

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown

📊 Benchmark Results

❌ Some benchmarks failed

Gate failures

  • CrocoApp constructor: p75 6.6μs exceeds baseline 3.4μs by more than 20%
  • CrocoApp lambdaHandler (10 controllers): p75 178.4μs exceeds baseline 33.3μs by more than 20%
  • Lambda cold-start simulation: p75 312.9μs exceeds baseline 70.2μs by more than 20%
  • Lambda cold-start with headers: p75 274.6μs exceeds baseline 66.7μs by more than 20%
  • Lambda cold-start with binary body: p75 238.7μs exceeds baseline 63.2μs by more than 20%
  • Lambda cold-start with query params: p75 214.5μs exceeds baseline 63.9μs by more than 20%
  • Lambda cold-start with authorizer context: p75 216.1μs exceeds baseline 59.8μs by more than 20%
  • Lambda cold-start realistic scenario: p75 214.5μs exceeds baseline 60.2μs by more than 20%
  • EventBusConfig.start (10 handlers): p75 1.5μs exceeds baseline 0.9μs by more than 20%
  • EventPublisher.publishNow single event: p75 1.6μs exceeds baseline 1.1μs by more than 20%
  • DefaultHandlerResolver.resolve × 10: p75 0.1μs exceeds baseline 0.0μs by more than 20%
  • Container.get singleton (cold): p75 47.5μs exceeds baseline 0.6μs by more than 20%
  • Container.register × 50 components: p75 2.2ms exceeds baseline 12.1μs by more than 20%
  • Container.validate (50 components): p75 2.6ms exceeds baseline 29.7μs by more than 20%
  • Container.get singleton (warm): p75 1.3μs exceeds baseline 0.3μs by more than 20%
Benchmark p75 Threshold Baseline vs Baseline Status Notes
CrocoApp constructor 6.6μs 30.0ms 3.4μs +95.2% -
CrocoApp lambdaHandler (10 controllers) 178.4μs 50.0ms 33.3μs +436.0% -
Lambda cold-start simulation 312.9μs 80.0ms 70.2μs +345.9% -
Lambda cold-start with headers 274.6μs 80.0ms 66.7μs +311.4% -
Lambda cold-start with binary body 238.7μs 80.0ms 63.2μs +277.9% -
Lambda cold-start with query params 214.5μs 80.0ms 63.9μs +235.8% -
Lambda cold-start with authorizer context 216.1μs 80.0ms 59.8μs +261.5% -
Lambda cold-start realistic scenario 214.5μs 80.0ms 60.2μs +256.5% -
EventBusConfig.start (10 handlers) 1.5μs 10.0ms 0.9μs +68.2% -
EventPublisher.publishNow single event 1.6μs 2.0ms 1.1μs +45.2% -
DefaultHandlerResolver.resolve × 10 0.1μs 5.0ms 0.0μs +42.9% -
Container.get singleton (cold) 47.5μs 5.0ms 0.6μs +7501.9% -
Container.register × 50 components 2.2ms 10.0ms 12.1μs +17635.7% -
Container.validate (50 components) 2.6ms 20.0ms 29.7μs +8747.4% -
Container.get singleton (warm) 1.3μs 500.0μs 0.3μs +356.2% -
TelemetryRuntime.init (lambda preset) 835.4μs 200.0ms 69.3ms -98.8% -
lambdaPreset config creation 1.1μs 2.0ms 1.0μs +5.1% -

Updated: 2026-06-30T07:08:33.150Z · Commit: 55275a6

@kang-heewon
kang-heewon force-pushed the fix/971-stable-cli-diagnostic-codes branch 2 times, most recently from 5fee764 to acf4eeb Compare June 29, 2026 15:19

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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/cli/src/commands/diCheck.ts`:
- Around line 208-217: The manifest parsing in diCheck is still exposing legacy
slash-form identifiers as the primary code; update the code path in diCheck to
normalize known legacy values before returning the diagnostic object. In the
record parsing logic, map any legacy manifest code found via
readOptionalString(record, "code") to the stable CROCO_* equivalent, and keep
the original value only in legacyCode so the returned object always surfaces the
stable code first.

In `@packages/cli/src/commands/jobs.ts`:
- Around line 119-133: `jobsHttpError` is using inconsistent categories between
`JobsHttpProblem` and `JOBS_HTTP_PROBLEM_REGISTRY_ENTRY`. Update
`JobsHttpProblem` and the registry entry so the same
`CLI_DIAGNOSTIC_CODES.jobsHttpError` maps to one stable `ProblemCategory`, or
split the 404 case into a separate diagnostic code and registry entry. Make sure
the symbols `JobsHttpProblem` and `JOBS_HTTP_PROBLEM_REGISTRY_ENTRY` stay
aligned so the problem registry indexes the correct category/status.

In `@packages/cli/src/libs/diagnosticCodes.ts`:
- Around line 53-55: `projectMapFrameworkManifestDiagnostic`와
`projectMapContractGraphDiagnostic`의 `legacyCode`에 와일드카드 문자열을 직접 넣는 방식이 문제입니다.
`withLegacyCode()`가 `extensions.legacyCode`를 그대로 직렬화하므로, `diagnosticCodes`에서
`project-map/...-*` 상수를 유지하지 말고 `withLegacyCode`/관련 helper 기준으로 감싼 원본 코드에서 구체적인
slash-form legacy alias를 생성하도록 분리하세요. `projectMapFrameworkManifestDiagnostic`,
`projectMapContractGraphDiagnostic`, and `withLegacyCode`를 찾아 이 두 케이스가 명시적
legacyCode를 보존하도록 수정하면 됩니다.

In `@scripts/problem-registry.mts`:
- Around line 798-810: 문제는 problem-registry.mts의 경로 필터링에서
normalizedCandidate.startsWith(rootDir + "/")를 사용해 Windows의 경로 구분자와 맞지 않는다는
점입니다. candidates를 검사하는 find 로직에서 resolve된 경로를 rootDir 기준으로 path.relative() 같은
정규화된 상대 경로 비교로 바꾸고, 상대 경로가 루트 밖으로 나가는 경우만 제외하도록 수정하세요. 이 변경은 sourceFilePath 계산과
관련된 candidate 필터링 전체에 적용해 OS 간 동작을 일관되게 유지해야 합니다.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 061f9d7a-4567-4164-9ae6-0f7385354f77

📥 Commits

Reviewing files that changed from the base of the PR and between d04a78e and 5fee764.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (26)
  • .changeset/stable-cli-diagnostic-codes.md
  • docs/problem-code-registry.json
  • docs/troubleshooting/diagnostics.md
  • packages/cli/package.json
  • packages/cli/src/commands/diCheck.ts
  • packages/cli/src/commands/doctor.ts
  • packages/cli/src/commands/generateUsageDashboard.ts
  • packages/cli/src/commands/jobs.ts
  • packages/cli/src/commands/projectMap.ts
  • packages/cli/src/libs/diagnosticCodes.ts
  • packages/cli/src/libs/ops.ts
  • packages/cli/src/tests/diCheck.spec.ts
  • packages/cli/src/tests/diagnosticCodes.spec.ts
  • packages/cli/src/tests/doctor.spec.ts
  • packages/cli/src/tests/generateUsageDashboard.spec.ts
  • packages/cli/src/tests/jobs.spec.ts
  • packages/cli/src/tests/opsStatus.spec.ts
  • packages/cli/src/tests/projectMap.spec.ts
  • packages/cli/vitest.config.ts
  • packages/diagnostics-core/src/libs/DiagnosticCodes.ts
  • packages/diagnostics-core/src/tests/DiagnosticCodes.spec.ts
  • packages/docs/src/content/docs/en/reference/problem-recovery-cookbook.md
  • scripts/problem-registry.mts
  • scripts/strict-contract-typecheck.mts
  • scripts/tests/problem-registry.spec.ts
  • scripts/tests/strict-contract-typecheck.spec.ts

Comment thread packages/cli/src/commands/diCheck.ts Outdated
Comment thread packages/cli/src/commands/jobs.ts
Comment thread packages/cli/src/libs/diagnosticCodes.ts Outdated
Comment thread scripts/problem-registry.mts Outdated
@kang-heewon
kang-heewon force-pushed the fix/971-stable-cli-diagnostic-codes branch from acf4eeb to 66d0996 Compare June 29, 2026 15:36
@kang-heewon
kang-heewon force-pushed the fix/971-stable-cli-diagnostic-codes branch 2 times, most recently from 3f006fc to 5ca1480 Compare June 29, 2026 16:32

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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/cli/src/commands/diCheck.ts`:
- Around line 212-220: The `diCheck` normalization logic is still letting
unmapped slash-form diagnostics leak into the primary `code` via `stableCode ??
rawCode`, which breaks the stable `CROCO_*` surface; update the
`code`/`legacyCode` mapping in `diCheck.ts` so any `cli/...` or `doctor/...`
value without a known stable mapping becomes
`CLI_DIAGNOSTIC_CODES.diCheckDiagnosticUnknown` in `code`, while preserving the
original string only in `legacyCode` through the existing
`getStableCliDiagnosticCodeForLegacyCode`, `readOptionalString`, and
`CLI_LEGACY_DIAGNOSTIC_CODES` flow.

In `@packages/cli/src/commands/generateUsageDashboard.ts`:
- Around line 298-341: `UsageDashboardProblem.toJSON()` is rebuilding the
payload manually instead of extending the parent `Problem` serialization. Update
`UsageDashboardProblem` to call `super.toJSON()` and only append `legacyCode`,
so `instance`, `extensions`, and the parent’s `title`/`status` mapping remain
intact. Keep the existing `UsageDashboardProblem` and
`usageDashboardProblemMetadata` symbols in place only if still needed, but avoid
duplicating serialization logic in `toJSON()`.

In `@packages/cli/src/commands/projectMap.ts`:
- Around line 647-648: The static legacyCode strings in projectMap are
duplicated against CLI_LEGACY_DIAGNOSTIC_CODES, so update the remaining
diagnostics in projectMap to read from the shared legacy-code table instead of
hardcoding aliases. Reuse the same central lookup pattern already used for
dynamic cases, and apply it consistently across projectMapContractRouteConflict
and the other runtime-*, package-manifest-conflict, and manifest-* entries so
emitter and normalizer stay in sync.

In `@packages/cli/src/tests/diagnosticCodes.spec.ts`:
- Around line 39-53: The regression test in diagnosticCodes.spec.ts is too easy
to bypass because it only matches direct string literals in code assignments,
readonly code, and super calls. Strengthen the check in the existing test by
moving from the current regex scan to an AST-based analysis that traces actual
code values in CLI producers under commands and libs, so indirect patterns like
const/helper-returned slash-form codes are still detected. Use the current test
name and the primarySlashCodePattern/offenders logic as the place to update the
implementation.

In `@packages/diagnostics-core/src/libs/DiagnosticCodes.ts`:
- Around line 384-395: The shared legacy alias cli/jobs-http-error is being
reused by two stable diagnostics, which breaks the reverse lookup behavior in
LEGACY_TO_STABLE_DIAGNOSTIC_CODES. Update the diagnostic definitions around
CROCO_CLI_JOBS_004 and CROCO_CLI_JOBS_005 in DiagnosticCodes so each stable code
has its own unique legacy code, or remove the duplicate alias from one of them
if 404 should remain a separate stable diagnostic. Ensure
getStableCliDiagnosticCodeForLegacyCode can map each legacy code to exactly one
stable code.

In
`@packages/docs/src/content/docs/api/diagnostics-core/src/variables/CROCO_DIAGNOSTIC_CODE_DEFINITIONS.md`:
- Line 8: 생성된 diagnostics API 문서에서 CROCO_CLI_* 항목이 helper 링크 반복으로 축약되어 실제 정의가
보이지 않는 문제를 해결해야 합니다. CROCO_DIAGNOSTIC_CODE_DEFINITIONS를 만드는 문서 생성 로직 또는 원본 소스에서
새 CLI 항목의 title, action, legacyCodes가 이 페이지에 인라인으로 펼쳐지도록 바꾸고,
DiagnosticCodeDefinition 참조만 반복 출력되지 않게 조정하세요.
CROCO_DIAGNOSTIC_CODE_DEFINITIONS와 DiagnosticCodeDefinition 관련 생성 경로를 확인해 CLI
정의가 문서에 실제 객체 형태로 노출되도록 수정하세요.

In `@scripts/problem-registry.mts`:
- Around line 789-826: `resolveImportedSourceFile`에서 동일한 임포트 대상이 여러 번
`readFileSync`와 `ts.createSourceFile`로 반복 파싱되고 있으니, 절대 경로 기준 캐시를 추가해 중복 작업을
막아주세요. `discoverProblemCodeCandidates` 호출 경로에서 재사용되도록
`resolveImportedSourceFile`, `sourceFilePath`, `ts.createSourceFile` 기준으로 메모이즈를
넣고, 이미 파싱된 모듈은 캐시된 `ts.SourceFile`을 반환하도록 수정하세요.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e27d5dd7-c8fe-4651-a457-e14af7cfbec0

📥 Commits

Reviewing files that changed from the base of the PR and between 5fee764 and 3f006fc.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (29)
  • .changeset/stable-cli-diagnostic-codes.md
  • docs/problem-code-registry.json
  • docs/troubleshooting/diagnostics.md
  • packages/cli/package.json
  • packages/cli/src/commands/diCheck.ts
  • packages/cli/src/commands/doctor.ts
  • packages/cli/src/commands/generateUsageDashboard.ts
  • packages/cli/src/commands/jobs.ts
  • packages/cli/src/commands/projectMap.ts
  • packages/cli/src/libs/diagnosticCodes.ts
  • packages/cli/src/libs/ops.ts
  • packages/cli/src/tests/diCheck.spec.ts
  • packages/cli/src/tests/diagnosticCodes.spec.ts
  • packages/cli/src/tests/doctor.spec.ts
  • packages/cli/src/tests/generateUsageDashboard.spec.ts
  • packages/cli/src/tests/jobs.spec.ts
  • packages/cli/src/tests/opsStatus.spec.ts
  • packages/cli/src/tests/projectMap.spec.ts
  • packages/cli/vitest.config.ts
  • packages/diagnostics-core/src/libs/DiagnosticCodes.ts
  • packages/diagnostics-core/src/tests/DiagnosticCodes.spec.ts
  • packages/docs/src/content/docs/api/cli/src/type-aliases/DiCheckDiagnostic.md
  • packages/docs/src/content/docs/api/cli/src/type-aliases/DoctorDiagnostic.md
  • packages/docs/src/content/docs/api/diagnostics-core/src/type-aliases/DiagnosticCodeDefinition.md
  • packages/docs/src/content/docs/api/diagnostics-core/src/variables/CROCO_DIAGNOSTIC_CODE_DEFINITIONS.md
  • packages/docs/src/content/docs/en/reference/problem-recovery-cookbook.md
  • scripts/problem-registry.mts
  • scripts/strict-contract-typecheck.mts
  • scripts/tests/problem-registry.spec.ts

Comment thread packages/cli/src/commands/diCheck.ts
Comment thread packages/cli/src/commands/generateUsageDashboard.ts Outdated
Comment thread packages/cli/src/commands/projectMap.ts Outdated
Comment thread packages/cli/src/tests/diagnosticCodes.spec.ts
Comment thread packages/diagnostics-core/src/libs/DiagnosticCodes.ts
Comment thread scripts/problem-registry.mts
@kang-heewon

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@kang-heewon
kang-heewon force-pushed the fix/971-stable-cli-diagnostic-codes branch from 5ca1480 to 3751b55 Compare June 29, 2026 17:24

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

♻️ Duplicate comments (2)
packages/cli/src/tests/diagnosticCodes.spec.ts (1)

169-171: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

가져온 legacy 코드 상수는 현재 스캐너가 놓칩니다.

resolveStringExpression()은 같은 파일에서 수집한 바인딩만 해석해서 super(CLI_LEGACY_DIAGNOSTIC_CODES.jobsHttpError) 같은 케이스를 undefined로 흘려보냅니다. 그러면 slash-form 1차 코드가 다시 들어와도 Line 46 테스트가 통과할 수 있습니다. 이 PR의 회귀 방지 목적이라면 imported legacy alias도 해석해야 합니다.

수정 예시
  if (ts.isPropertyAccessExpression(unwrapped)) {
-    return bindings.propertyAccesses.get(unwrapped.getText());
+    const importedLegacyCode =
+      ts.isIdentifier(unwrapped.expression) &&
+      unwrapped.expression.text === "CLI_LEGACY_DIAGNOSTIC_CODES"
+        ? CLI_LEGACY_DIAGNOSTIC_CODES[
+            unwrapped.name.text as keyof typeof CLI_LEGACY_DIAGNOSTIC_CODES
+          ]
+        : undefined;
+
+    return importedLegacyCode ?? bindings.propertyAccesses.get(unwrapped.getText());
  }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/src/tests/diagnosticCodes.spec.ts` around lines 169 - 171,
`resolveStringExpression()` is only resolving property accesses from local
bindings, so imported legacy diagnostic constants like
`super(CLI_LEGACY_DIAGNOSTIC_CODES.jobsHttpError)` are being treated as
unresolved. Update the resolver used in `diagnosticCodes.spec.ts` to also follow
imported legacy aliases when handling
`ts.isPropertyAccessExpression(unwrapped)`, so it can map the imported symbol to
the actual string value instead of returning undefined. Keep the existing local
binding lookup in `bindings.propertyAccesses.get(...)`, but extend the lookup
path to cover imported legacy constants in the same resolution flow.
packages/cli/src/commands/diCheck.ts (1)

215-225: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

CLI legacy prefix 판별이 아직 일부 namespace만 다룹니다.

isCliLegacyDiagnosticCode()cli/doctor/만 legacy로 취급해서, 이번 마이그레이션 범위에 포함된 project-map/...·usage-dashboard/... 같은 미등록 slash-form 값은 Line 218에서 그대로 code로 다시 노출됩니다. 그러면 stable CROCO_* surface 보장이 깨지므로, 여기 판별을 전체 CLI legacy namespace 기준으로 넓히거나 중앙화된 테이블로 옮겨서 unknown stable code로 정규화해야 합니다.

수정 예시
+const CLI_LEGACY_DIAGNOSTIC_PREFIXES = [
+  "cli/",
+  "doctor/",
+  "project-map/",
+  "usage-dashboard/",
+] as const;
+
 function isCliLegacyDiagnosticCode(code: string): boolean {
-  return code.startsWith("cli/") || code.startsWith("doctor/");
+  return CLI_LEGACY_DIAGNOSTIC_PREFIXES.some((prefix) => code.startsWith(prefix));
 }

Also applies to: 239-240

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/src/commands/diCheck.ts` around lines 215 - 225,
isCliLegacyDiagnosticCode() only treats a subset of slash-form namespaces as
legacy, so unmapped values like project-map/... and usage-dashboard/... can
still leak back out as code in diCheck’s normalization path. Update the
legacy-diagnostic detection used in diCheck.ts to cover all CLI legacy
namespaces (or centralize the namespace list/table) so any non-stable slash-form
code is mapped to CLI_DIAGNOSTIC_CODES.diCheckDiagnosticUnknown and only the
stable CROCO_* surface is emitted; make sure the legacyCode derivation in the
same block follows the same expanded classification.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/cli/src/commands/generateUsageDashboard.ts`:
- Line 282: In the generateUsageDashboard template, the generated
UsageDashboardProblems.ts currently mixes value imports and type-only imports in
the same import statement. Update the template in generateUsageDashboard so
ProblemDetails and ProblemOptions are emitted as a separate import type section,
while Problem and ProblemCategory remain in the normal value import; keep the
import block organized to match the TypeScript import-type and grouped import
rules.

---

Duplicate comments:
In `@packages/cli/src/commands/diCheck.ts`:
- Around line 215-225: isCliLegacyDiagnosticCode() only treats a subset of
slash-form namespaces as legacy, so unmapped values like project-map/... and
usage-dashboard/... can still leak back out as code in diCheck’s normalization
path. Update the legacy-diagnostic detection used in diCheck.ts to cover all CLI
legacy namespaces (or centralize the namespace list/table) so any non-stable
slash-form code is mapped to CLI_DIAGNOSTIC_CODES.diCheckDiagnosticUnknown and
only the stable CROCO_* surface is emitted; make sure the legacyCode derivation
in the same block follows the same expanded classification.

In `@packages/cli/src/tests/diagnosticCodes.spec.ts`:
- Around line 169-171: `resolveStringExpression()` is only resolving property
accesses from local bindings, so imported legacy diagnostic constants like
`super(CLI_LEGACY_DIAGNOSTIC_CODES.jobsHttpError)` are being treated as
unresolved. Update the resolver used in `diagnosticCodes.spec.ts` to also follow
imported legacy aliases when handling
`ts.isPropertyAccessExpression(unwrapped)`, so it can map the imported symbol to
the actual string value instead of returning undefined. Keep the existing local
binding lookup in `bindings.propertyAccesses.get(...)`, but extend the lookup
path to cover imported legacy constants in the same resolution flow.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 53c7eab6-d22b-4a1a-a5f9-b3de049b4996

📥 Commits

Reviewing files that changed from the base of the PR and between 3f006fc and 3751b55.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (29)
  • .changeset/stable-cli-diagnostic-codes.md
  • docs/problem-code-registry.json
  • docs/troubleshooting/diagnostics.md
  • packages/cli/package.json
  • packages/cli/src/commands/diCheck.ts
  • packages/cli/src/commands/doctor.ts
  • packages/cli/src/commands/generateUsageDashboard.ts
  • packages/cli/src/commands/jobs.ts
  • packages/cli/src/commands/projectMap.ts
  • packages/cli/src/libs/diagnosticCodes.ts
  • packages/cli/src/libs/ops.ts
  • packages/cli/src/tests/diCheck.spec.ts
  • packages/cli/src/tests/diagnosticCodes.spec.ts
  • packages/cli/src/tests/doctor.spec.ts
  • packages/cli/src/tests/generateUsageDashboard.spec.ts
  • packages/cli/src/tests/jobs.spec.ts
  • packages/cli/src/tests/opsStatus.spec.ts
  • packages/cli/src/tests/projectMap.spec.ts
  • packages/cli/vitest.config.ts
  • packages/diagnostics-core/src/libs/DiagnosticCodes.ts
  • packages/diagnostics-core/src/tests/DiagnosticCodes.spec.ts
  • packages/docs/src/content/docs/api/cli/src/type-aliases/DiCheckDiagnostic.md
  • packages/docs/src/content/docs/api/cli/src/type-aliases/DoctorDiagnostic.md
  • packages/docs/src/content/docs/api/diagnostics-core/src/type-aliases/DiagnosticCodeDefinition.md
  • packages/docs/src/content/docs/api/diagnostics-core/src/variables/CROCO_DIAGNOSTIC_CODE_DEFINITIONS.md
  • packages/docs/src/content/docs/en/reference/problem-recovery-cookbook.md
  • scripts/problem-registry.mts
  • scripts/strict-contract-typecheck.mts
  • scripts/tests/problem-registry.spec.ts

Comment thread packages/cli/src/commands/generateUsageDashboard.ts Outdated
@kang-heewon
kang-heewon force-pushed the fix/971-stable-cli-diagnostic-codes branch 2 times, most recently from d125e0f to dddd5b2 Compare June 30, 2026 06:22

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
packages/cli/src/tests/diagnosticCodes.spec.ts (1)

54-75: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

CLI_LEGACY_DIAGNOSTIC_CODES를 지역 변수에 담으면 회귀 검사가 비켜갑니다.

collectStringBindings()는 문자열 리터럴/객체 리터럴만 식별자 바인딩으로 저장해서 const code = CLI_LEGACY_DIAGNOSTIC_CODES.jobsHttpError; super(code, ...) 같은 형태를 해석하지 못합니다. 그래서 Line 46 회귀 테스트는 slash-form 1차 코드를 다시 primary code로 써도 통과할 수 있습니다.

🔧 최소 수정 예시
 function collectStringBindings(sourceFile: ts.SourceFile): StringBindings {
   const identifiers = new Map<string, string>();
   const propertyAccesses = new Map<string, string>();

   const visit = (node: ts.Node): void => {
     if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.initializer) {
       const initializer = unwrapExpression(node.initializer);
-      const value = readStringLiteral(initializer);
+      const value =
+        readStringLiteral(initializer) ??
+        resolveStringExpression(initializer, { identifiers, propertyAccesses });

       if (value) {
         identifiers.set(node.name.text, value);
       }

Also applies to: 161-221

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/src/tests/diagnosticCodes.spec.ts` around lines 54 - 75,
`collectStringBindings()` currently only records direct string/object-literal
bindings, so an alias like `const code =
CLI_LEGACY_DIAGNOSTIC_CODES.jobsHttpError` can bypass the primary-code scan.
Update the binding collection and/or `resolveStringExpression()` path to follow
identifier aliases back to the imported legacy diagnostic constant, using
`collectStringBindings`, `findFirstSuperArgument`, and `resolveStringExpression`
as the main entry points. Also extend the `diagnosticCodes.spec.ts` coverage
with a case that stores `CLI_LEGACY_DIAGNOSTIC_CODES.jobsHttpError` in a local
variable before passing it to `super(...)`, so the regression is caught.
🤖 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 `@docs/troubleshooting/diagnostics.md`:
- Line 161: legacyCode alias 설명이 너무 뭉뚱그려져 있어 migration lookup에 필요한 개별 slash-form
값을 알 수 없습니다. diagnostics 문서의 legacy alias 안내를 수정해,
project-map/framework-manifest-* 및 project-map/contract-graph-* 같은 와일드카드 대신 실제
개별 alias를 모두 명시하거나, 개별 alias를 보존하지 않는다는 점을 diagnostics의 code/legacyCode 규칙과 함께
분명히 적어주세요.

In `@packages/cli/src/commands/diCheck.ts`:
- Around line 239-247: `isCliLegacyDiagnosticCode()` currently only classifies a
few legacy slash-form prefixes, so `jobs/`, `ops/`, and `di-check/` can still
leak through as stable CLI codes. Update `CLI_LEGACY_DIAGNOSTIC_PREFIXES` in
`diCheck.ts` to include those prefixes so the existing slash-form-to-`CROCO_*`
fallback applies, and add matching regression coverage in `diCheck.spec.ts` for
these codes to ensure they are normalized consistently.

---

Duplicate comments:
In `@packages/cli/src/tests/diagnosticCodes.spec.ts`:
- Around line 54-75: `collectStringBindings()` currently only records direct
string/object-literal bindings, so an alias like `const code =
CLI_LEGACY_DIAGNOSTIC_CODES.jobsHttpError` can bypass the primary-code scan.
Update the binding collection and/or `resolveStringExpression()` path to follow
identifier aliases back to the imported legacy diagnostic constant, using
`collectStringBindings`, `findFirstSuperArgument`, and `resolveStringExpression`
as the main entry points. Also extend the `diagnosticCodes.spec.ts` coverage
with a case that stores `CLI_LEGACY_DIAGNOSTIC_CODES.jobsHttpError` in a local
variable before passing it to `super(...)`, so the regression is caught.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: eb5af13c-30fe-4418-8b25-649caa061aa2

📥 Commits

Reviewing files that changed from the base of the PR and between 3751b55 and dddd5b2.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (30)
  • .changeset/stable-cli-diagnostic-codes.md
  • docs/problem-code-registry.json
  • docs/troubleshooting/diagnostics.md
  • packages/cli/package.json
  • packages/cli/src/commands/diCheck.ts
  • packages/cli/src/commands/doctor.ts
  • packages/cli/src/commands/generateUsageDashboard.ts
  • packages/cli/src/commands/jobs.ts
  • packages/cli/src/commands/projectMap.ts
  • packages/cli/src/libs/diagnosticCodes.ts
  • packages/cli/src/libs/ops.ts
  • packages/cli/src/tests/diCheck.spec.ts
  • packages/cli/src/tests/diagnosticCodes.spec.ts
  • packages/cli/src/tests/doctor.spec.ts
  • packages/cli/src/tests/generateUsageDashboard.spec.ts
  • packages/cli/src/tests/integration/e2e.spec.ts
  • packages/cli/src/tests/jobs.spec.ts
  • packages/cli/src/tests/opsStatus.spec.ts
  • packages/cli/src/tests/projectMap.spec.ts
  • packages/cli/vitest.config.ts
  • packages/diagnostics-core/src/libs/DiagnosticCodes.ts
  • packages/diagnostics-core/src/tests/DiagnosticCodes.spec.ts
  • packages/docs/src/content/docs/api/cli/src/type-aliases/DiCheckDiagnostic.md
  • packages/docs/src/content/docs/api/cli/src/type-aliases/DoctorDiagnostic.md
  • packages/docs/src/content/docs/api/diagnostics-core/src/type-aliases/DiagnosticCodeDefinition.md
  • packages/docs/src/content/docs/api/diagnostics-core/src/variables/CROCO_DIAGNOSTIC_CODE_DEFINITIONS.md
  • packages/docs/src/content/docs/en/reference/problem-recovery-cookbook.md
  • scripts/problem-registry.mts
  • scripts/strict-contract-typecheck.mts
  • scripts/tests/problem-registry.spec.ts

Comment thread docs/troubleshooting/diagnostics.md
Comment thread packages/cli/src/commands/diCheck.ts
@kang-heewon
kang-heewon force-pushed the fix/971-stable-cli-diagnostic-codes branch from dddd5b2 to 9144e23 Compare June 30, 2026 06:57
@kang-heewon
kang-heewon force-pushed the fix/971-stable-cli-diagnostic-codes branch from 9144e23 to de74608 Compare June 30, 2026 07:02
@kang-heewon
kang-heewon merged commit 3ca4a69 into trunk Jun 30, 2026
8 of 9 checks passed
@kang-heewon
kang-heewon deleted the fix/971-stable-cli-diagnostic-codes branch June 30, 2026 07:39
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.

[diagnostics] Migrate CLI diagnostics to stable CROCO_* codes

1 participant