commitgate 0.9.8 → 0.9.10
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.
- package/CHANGELOG.md +34 -0
- package/bin/dispatch.mjs +3 -0
- package/bin/init.ts +21 -3
- package/bin/migrate.ts +29 -11
- package/bin/sync.ts +200 -17
- package/bin/uninstall.ts +75 -6
- package/package.json +76 -76
- package/scripts/req/lib/adapters.ts +113 -7
- package/scripts/req/lib/close-migrate.ts +135 -0
- package/scripts/req/lib/close-proof.ts +323 -0
- package/scripts/req/lib/config.ts +9 -0
- package/scripts/req/lib/evidence-ports.ts +8 -1
- package/scripts/req/lib/evidence.ts +158 -3
- package/scripts/req/lib/intake.ts +175 -0
- package/scripts/req/lib/lockfile-diff.ts +127 -0
- package/scripts/req/lib/reconstruct.ts +118 -0
- package/scripts/req/lib/review-exception.ts +233 -0
- package/scripts/req/lib/review-ledger.ts +257 -0
- package/scripts/req/lib/review-target.ts +72 -0
- package/scripts/req/lib/scratch.ts +14 -1
- package/scripts/req/lib/state-checkpoint.ts +78 -0
- package/scripts/req/req-close.ts +222 -0
- package/scripts/req/req-commit.ts +805 -623
- package/scripts/req/req-doctor.ts +58 -1
- package/scripts/req/req-new.ts +304 -255
- package/scripts/req/req-next.ts +848 -813
- package/scripts/req/req-reconstruct.ts +224 -0
- package/scripts/req/req-review-exception.ts +197 -0
- package/scripts/req/review-codex.ts +2547 -2146
- package/workflow/req.config.schema.json +3 -0
- package/workflow/review-persona.md +8 -0
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
type Verdict,
|
|
29
29
|
type ApprovalEvidence,
|
|
30
30
|
} from './review-codex'
|
|
31
|
-
import { loadConfig, packageRoot, stripBom, DEFAULTS, type ResolvedConfig } from './lib/config'
|
|
31
|
+
import { loadConfig, packageRoot, stripBom, DEFAULTS, type ResolvedConfig, type PackageManager } from './lib/config'
|
|
32
32
|
import { createGitAdapter, type GitAdapter } from './lib/adapters'
|
|
33
33
|
import { missingQuickstartFiles } from '../../bin/quickstart'
|
|
34
34
|
|
|
@@ -109,6 +109,11 @@ export interface DoctorInputs {
|
|
|
109
109
|
// undefined = 미계산(2-arg/legacy) → OK. [] = 전부 보호됨 → OK. 비어있지 않음 → WARN.
|
|
110
110
|
// dev/dogfood(packageRootDiffers===false)면 D20/D21처럼 skip. optional이어야 테스트 base 리터럴이 안 깨진다.
|
|
111
111
|
repoRootScratchUnprotected?: string[]
|
|
112
|
+
// D23(REQ-2026-056): frozen-lockfile 위생. 감지된 PM의 lockfile이 없거나 untracked면 재현 가능한 설치
|
|
113
|
+
// (`<pm> ci`/`--frozen-lockfile`)가 불가하다. undefined = 미계산(2-arg/legacy) → OK.
|
|
114
|
+
// 'no-package-json'/'ok' → OK. 'missing'/'untracked' → **WARN**(FAIL 아님 — D19~D22 근거 동일).
|
|
115
|
+
// optional이어야 테스트 base 리터럴이 안 깨진다.
|
|
116
|
+
lockfileStatus?: 'ok' | 'missing' | 'untracked' | 'no-package-json'
|
|
112
117
|
}
|
|
113
118
|
|
|
114
119
|
/**
|
|
@@ -508,6 +513,26 @@ export function runChecks(inp: DoctorInputs): Check[] {
|
|
|
508
513
|
})
|
|
509
514
|
}
|
|
510
515
|
|
|
516
|
+
// D23(REQ-2026-056): frozen-lockfile 위생 진단.
|
|
517
|
+
//
|
|
518
|
+
// 🔴 **level 상한은 WARN — 절대 FAIL이 아니다**(D19~D22와 동일 근거). `req:commit`이 doctor를 하드 게이트로
|
|
519
|
+
// spawn하므로 FAIL이면 lockfile 없는 프로젝트의 모든 커밋이 벽돌이 된다. lockfile ↔ package.json 동기
|
|
520
|
+
// 여부는 검사하지 않는다(PM 실행 없이 신뢰 불가) — 존재·tracked 위생만.
|
|
521
|
+
if (inp.lockfileStatus === undefined || inp.lockfileStatus === 'ok') {
|
|
522
|
+
c.push({ id: 'D23', level: 'OK', msg: inp.lockfileStatus === undefined ? 'lockfile 위생 점검 불요(미계산)' : 'lockfile 존재·git-tracked — 재현 가능한 설치(--frozen-lockfile) 가능' })
|
|
523
|
+
} else if (inp.lockfileStatus === 'no-package-json') {
|
|
524
|
+
c.push({ id: 'D23', level: 'OK', msg: 'lockfile 위생 점검 불요(package.json 없음)' })
|
|
525
|
+
} else {
|
|
526
|
+
c.push({
|
|
527
|
+
id: 'D23',
|
|
528
|
+
level: 'WARN',
|
|
529
|
+
msg:
|
|
530
|
+
inp.lockfileStatus === 'missing'
|
|
531
|
+
? '감지된 패키지 매니저의 lockfile이 없습니다 — 재현 가능한 설치(`<pm> ci` / `--frozen-lockfile`)가 불가합니다. lockfile을 생성·커밋하세요.'
|
|
532
|
+
: 'lockfile이 git-tracked가 아닙니다(untracked) — 재현 가능한 설치가 불가합니다. lockfile을 커밋하세요.',
|
|
533
|
+
})
|
|
534
|
+
}
|
|
535
|
+
|
|
511
536
|
return c
|
|
512
537
|
}
|
|
513
538
|
|
|
@@ -651,6 +676,29 @@ function safeReadVersion(pkgAbs: string): string | null {
|
|
|
651
676
|
}
|
|
652
677
|
}
|
|
653
678
|
|
|
679
|
+
/** PM별 기대 lockfile 후보(npm은 둘 다 유효). */
|
|
680
|
+
const LOCKFILES_FOR_PM: Record<PackageManager, string[]> = {
|
|
681
|
+
npm: ['package-lock.json', 'npm-shrinkwrap.json'],
|
|
682
|
+
pnpm: ['pnpm-lock.yaml'],
|
|
683
|
+
yarn: ['yarn.lock'],
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* frozen-lockfile 위생 판정(D23·REQ-2026-056). package.json 없으면 점검 불요. PM 기대 lockfile이 하나라도
|
|
688
|
+
* 존재+tracked면 ok, 존재하나 전부 untracked면 untracked, 하나도 없으면 missing.
|
|
689
|
+
* 🔴 lockfile↔package.json **동기 검사는 안 한다**(PM 실행 없이 신뢰 불가) — 존재·tracked 위생만.
|
|
690
|
+
*/
|
|
691
|
+
export function lockfileHygiene(
|
|
692
|
+
root: string,
|
|
693
|
+
pm: PackageManager,
|
|
694
|
+
isTracked: (rel: string) => boolean,
|
|
695
|
+
): 'ok' | 'missing' | 'untracked' | 'no-package-json' {
|
|
696
|
+
if (!existsSync(join(root, 'package.json'))) return 'no-package-json'
|
|
697
|
+
const present = LOCKFILES_FOR_PM[pm].filter((f) => existsSync(join(root, f)))
|
|
698
|
+
if (present.length === 0) return 'missing'
|
|
699
|
+
return present.some((f) => isTracked(f)) ? 'ok' : 'untracked'
|
|
700
|
+
}
|
|
701
|
+
|
|
654
702
|
export function main(argv: string[] = process.argv.slice(2)): void {
|
|
655
703
|
const opts = parseArgs(argv)
|
|
656
704
|
const cfg = loadConfig({ root: opts.root })
|
|
@@ -760,6 +808,15 @@ export function main(argv: string[] = process.argv.slice(2)): void {
|
|
|
760
808
|
// D22(REQ-2026-047): 현재 repo-root 런타임 스크래치 축은 review-call 측정 로그 1건.
|
|
761
809
|
// 새 축이 생기면 이 배열에 추가하고 packed-consumer smoke 단언도 함께 늘린다(docs 인벤토리 표의 유지 규칙).
|
|
762
810
|
repoRootScratchUnprotected: unprotectedRepoRootScratch([REVIEW_CALL_LOG_REL], git),
|
|
811
|
+
// D23(REQ-2026-056): frozen-lockfile 위생(존재·tracked). tracked 판정은 read-only `git ls-files`.
|
|
812
|
+
lockfileStatus: lockfileHygiene(cfg.root, cfg.packageManager, (rel) => {
|
|
813
|
+
try {
|
|
814
|
+
git(['ls-files', '--error-unmatch', '--', rel])
|
|
815
|
+
return true
|
|
816
|
+
} catch {
|
|
817
|
+
return false
|
|
818
|
+
}
|
|
819
|
+
}),
|
|
763
820
|
}
|
|
764
821
|
|
|
765
822
|
const checks = runChecks(inp)
|