@ojokesusu/lintasai 1.2.0 → 1.2.1
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 +26 -0
- package/bin/lintasai.js +1 -0
- package/kit.ps1 +42 -3
- package/package.json +1 -1
- package/tests/setup-pola-b.Tests.ps1 +15 -7
- package/uninstall.ps1 +17 -6
package/CHANGELOG.md
CHANGED
|
@@ -20,6 +20,32 @@ Slot tambahan untuk perubahan berikutnya sebelum versi v1.0.2.
|
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
23
|
+
## v1.2.1 [2026-06-06]
|
|
24
|
+
|
|
25
|
+
### Fixed (Critical Follow-up to v1.2.0)
|
|
26
|
+
|
|
27
|
+
#### Uninstall Command via NPX
|
|
28
|
+
- `npx lintasai uninstall` previously failed karena uninstall.ps1 ignore -ProjectRoot param dan resolve via manifest project_root override
|
|
29
|
+
- Fix: When -ProjectRoot explicitly supplied via $PSBoundParameters, honor it as ground truth (npx mode)
|
|
30
|
+
- Manifest mismatch detection only runs ketika -ProjectRoot NOT supplied + -AllowProjectRootMismatch not set
|
|
31
|
+
|
|
32
|
+
#### Diff Command
|
|
33
|
+
- `npx lintasai diff` previously failed (bug di new Invoke-Diff function)
|
|
34
|
+
- Fix: Rewrite to use Get-FileHash + manifest comparison cleanly with proper $ProjectRoot scoping
|
|
35
|
+
|
|
36
|
+
#### Pester Tests Alignment
|
|
37
|
+
- 3 failing tests di setup-pola-b.Tests.ps1 adjusted untuk match actual script behavior
|
|
38
|
+
|
|
39
|
+
#### Code Quality
|
|
40
|
+
- L1-RUN-004: null comparison style ($null -ne $x) consistency across all .ps1 files
|
|
41
|
+
|
|
42
|
+
### Notes
|
|
43
|
+
- ALL 7 commands sekarang exit 0 (verified): init, version, doctor, status, diff, update, uninstall
|
|
44
|
+
- Pester 100% pass
|
|
45
|
+
- Distribution Verdict: GREEN
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
23
49
|
## v1.2.0 [2026-06-06]
|
|
24
50
|
|
|
25
51
|
### Fixed (Critical)
|
package/bin/lintasai.js
CHANGED
package/kit.ps1
CHANGED
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
[CmdletBinding()]
|
|
49
49
|
param(
|
|
50
50
|
[Parameter(Position = 0)]
|
|
51
|
-
[ValidateSet('setup', 'update', 'uninstall', 'doctor', 'scan', 'version', 'rollback', 'status', 'help', '')]
|
|
51
|
+
[ValidateSet('setup', 'update', 'uninstall', 'doctor', 'scan', 'version', 'rollback', 'status', 'diff', 'help', '')]
|
|
52
52
|
[string]$Command = '',
|
|
53
53
|
|
|
54
54
|
[string]$ProjectRoot = $null,
|
|
@@ -76,7 +76,7 @@ if ($ProjectRoot) {
|
|
|
76
76
|
|
|
77
77
|
# Inform user which kit is being inspected — penting buat differentiate "kit di project" vs
|
|
78
78
|
# "kit di npm cache". Subcommands yang inspect kit (doctor/version/rollback/scan) butuh ini.
|
|
79
|
-
if ($Command -in @('doctor', 'version', 'rollback', 'scan', 'status')) {
|
|
79
|
+
if ($Command -in @('doctor', 'version', 'rollback', 'scan', 'status', 'diff')) {
|
|
80
80
|
Write-Host ("Inspecting kit at: {0}" -f $KitDir) -ForegroundColor Cyan
|
|
81
81
|
}
|
|
82
82
|
|
|
@@ -260,7 +260,7 @@ function Invoke-Doctor {
|
|
|
260
260
|
$manifest = $null
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
-
if ($
|
|
263
|
+
if ($null -ne $manifest) {
|
|
264
264
|
$pristine = 0
|
|
265
265
|
$modifiedList = @()
|
|
266
266
|
$integrityMissing = 0
|
|
@@ -562,6 +562,41 @@ function Show-Version {
|
|
|
562
562
|
Write-Host (Get-KitVersion)
|
|
563
563
|
}
|
|
564
564
|
|
|
565
|
+
# ---- Helper: diff vs manifest ----
|
|
566
|
+
# Compare current file hashes vs sha256 di .install-manifest.json. Tampilkan file yang
|
|
567
|
+
# modified atau missing sejak install. Berguna buat user yang mau cek apakah ada yang
|
|
568
|
+
# tweaked file kit secara manual sebelum jalankan `update` atau `uninstall`.
|
|
569
|
+
function Invoke-Diff {
|
|
570
|
+
param([string]$ProjectRootResolved)
|
|
571
|
+
$kitDir = Join-Path $ProjectRootResolved ".claude-kit"
|
|
572
|
+
$manifestPath = Join-Path $kitDir ".install-manifest.json"
|
|
573
|
+
if (-not (Test-Path $manifestPath)) {
|
|
574
|
+
Write-Warning "Tidak ada manifest di $manifestPath. Kit belum di-install atau corrupt."
|
|
575
|
+
return 1
|
|
576
|
+
}
|
|
577
|
+
$manifest = Get-Content $manifestPath -Raw | ConvertFrom-Json
|
|
578
|
+
$modified = @()
|
|
579
|
+
$missing = @()
|
|
580
|
+
foreach ($entry in $manifest.files) {
|
|
581
|
+
$filePath = Join-Path $ProjectRootResolved $entry.path
|
|
582
|
+
if (-not (Test-Path $filePath)) {
|
|
583
|
+
$missing += $entry.path
|
|
584
|
+
} else {
|
|
585
|
+
$currentHash = (Get-FileHash -Algorithm SHA256 -Path $filePath).Hash.ToLower()
|
|
586
|
+
if ($currentHash -ne $entry.sha256.ToLower()) {
|
|
587
|
+
$modified += $entry.path
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
Write-Host "=== Kit Diff (vs manifest) ==="
|
|
592
|
+
Write-Host "Modified ($($modified.Count)):"
|
|
593
|
+
$modified | ForEach-Object { Write-Host " M $_" }
|
|
594
|
+
Write-Host ""
|
|
595
|
+
Write-Host "Missing ($($missing.Count)):"
|
|
596
|
+
$missing | ForEach-Object { Write-Host " - $_" }
|
|
597
|
+
return 0
|
|
598
|
+
}
|
|
599
|
+
|
|
565
600
|
# ---- Router ----
|
|
566
601
|
switch ($Command) {
|
|
567
602
|
'setup' {
|
|
@@ -605,6 +640,10 @@ switch ($Command) {
|
|
|
605
640
|
$code = Invoke-Status
|
|
606
641
|
exit $code
|
|
607
642
|
}
|
|
643
|
+
'diff' {
|
|
644
|
+
$code = Invoke-Diff -ProjectRootResolved $ProjectRoot
|
|
645
|
+
exit $code
|
|
646
|
+
}
|
|
608
647
|
'version' {
|
|
609
648
|
Show-Version
|
|
610
649
|
exit 0
|
package/package.json
CHANGED
|
@@ -33,6 +33,14 @@ BeforeAll {
|
|
|
33
33
|
$script:KitRepoRoot = Resolve-Path (Join-Path $PSScriptRoot '..') | Select-Object -ExpandProperty Path
|
|
34
34
|
$script:SetupScript = Join-Path $script:KitRepoRoot 'setup-pola-b.ps1'
|
|
35
35
|
|
|
36
|
+
# ---- Canonical TEMP (long form) ----
|
|
37
|
+
# $env:TEMP sering return 8.3 short path (mis. C:\Users\ADMINI~1\AppData\Local\Temp\2).
|
|
38
|
+
# Setup script pakai $PSScriptRoot (long form) untuk derive ProjectRoot di traditional
|
|
39
|
+
# mode, dan Resolve-Path tidak expand 8.3 -> long. Akibatnya: output script pakai long
|
|
40
|
+
# form, regex test pakai short form -> tidak match. Pakai (Get-Item).FullName supaya
|
|
41
|
+
# canonical long form di semua test path.
|
|
42
|
+
$script:TempCanonical = (Get-Item -LiteralPath $env:TEMP).FullName
|
|
43
|
+
|
|
36
44
|
if (-not (Test-Path $script:SetupScript)) {
|
|
37
45
|
throw "setup-pola-b.ps1 not found at $script:SetupScript - tests assume layout tests/ sibling to setup-pola-b.ps1"
|
|
38
46
|
}
|
|
@@ -104,7 +112,7 @@ BeforeAll {
|
|
|
104
112
|
Describe "setup-pola-b.ps1 Branch 1: traditional invocation (no -ProjectRoot)" {
|
|
105
113
|
BeforeAll {
|
|
106
114
|
# Layout: <tmp>/<project>/.claude-kit/setup-pola-b.ps1
|
|
107
|
-
$script:Root1 = Join-Path $
|
|
115
|
+
$script:Root1 = Join-Path $script:TempCanonical ("lintasAI-setup-test-traditional-{0}" -f ([guid]::NewGuid().ToString('N').Substring(0,8)))
|
|
108
116
|
$null = New-Item -ItemType Directory -Path $script:Root1 -Force
|
|
109
117
|
script:Add-ProjectContent -Root $script:Root1
|
|
110
118
|
$script:Kit1 = Join-Path $script:Root1 '.claude-kit'
|
|
@@ -138,7 +146,7 @@ Describe "setup-pola-b.ps1 Branch 2: -ProjectRoot supplied (valid path)" {
|
|
|
138
146
|
# Layout: <tmp>/<project>/.claude-kit/setup-pola-b.ps1 (kit lives standard place)
|
|
139
147
|
# but we ALSO pass -ProjectRoot explicitly to exercise the npx-mode code path
|
|
140
148
|
# bahkan kalau path-nya same. Script harus treat sebagai npx mode.
|
|
141
|
-
$script:Root2 = Join-Path $
|
|
149
|
+
$script:Root2 = Join-Path $script:TempCanonical ("lintasAI-setup-test-explicitroot-{0}" -f ([guid]::NewGuid().ToString('N').Substring(0,8)))
|
|
142
150
|
$null = New-Item -ItemType Directory -Path $script:Root2 -Force
|
|
143
151
|
script:Add-ProjectContent -Root $script:Root2
|
|
144
152
|
$script:Kit2 = Join-Path $script:Root2 '.claude-kit'
|
|
@@ -167,14 +175,14 @@ Describe "setup-pola-b.ps1 Branch 3: -ProjectRoot non-existent path" {
|
|
|
167
175
|
# Kit lives di TEMP/<kit-folder>/.claude-kit dengan parent project legit, tapi
|
|
168
176
|
# we pass -ProjectRoot ke path yang tidak ada -> Resolve-Path -ErrorAction Stop
|
|
169
177
|
# harus throw -> exit code non-zero, with clear error message (not silent).
|
|
170
|
-
$script:Root3 = Join-Path $
|
|
178
|
+
$script:Root3 = Join-Path $script:TempCanonical ("lintasAI-setup-test-badroot-{0}" -f ([guid]::NewGuid().ToString('N').Substring(0,8)))
|
|
171
179
|
$null = New-Item -ItemType Directory -Path $script:Root3 -Force
|
|
172
180
|
script:Add-ProjectContent -Root $script:Root3
|
|
173
181
|
$script:Kit3 = Join-Path $script:Root3 '.claude-kit'
|
|
174
182
|
script:Copy-RealKit -Destination $script:Kit3
|
|
175
183
|
$script:SetupInKit3 = Join-Path $script:Kit3 'setup-pola-b.ps1'
|
|
176
184
|
# Path yang DIJAMIN tidak ada
|
|
177
|
-
$script:BadRoot = Join-Path $
|
|
185
|
+
$script:BadRoot = Join-Path $script:TempCanonical ("lintasAI-DOES-NOT-EXIST-{0}" -f ([guid]::NewGuid().ToString('N').Substring(0,8)))
|
|
178
186
|
}
|
|
179
187
|
|
|
180
188
|
AfterAll {
|
|
@@ -206,12 +214,12 @@ Describe "setup-pola-b.ps1 Branch 4: -ProjectRoot + kit at npm-cache-like path"
|
|
|
206
214
|
# <tmp>\<project-root>\ (target project, beda parent)
|
|
207
215
|
# Script harus detect mismatch ($KitDir tidak dalam $ProjectRoot/.claude-kit/)
|
|
208
216
|
# dan COPY isi kit ke $ProjectRoot/.claude-kit/.
|
|
209
|
-
$script:Root4 = Join-Path $
|
|
217
|
+
$script:Root4 = Join-Path $script:TempCanonical ("lintasAI-setup-test-npx-{0}" -f ([guid]::NewGuid().ToString('N').Substring(0,8)))
|
|
210
218
|
$null = New-Item -ItemType Directory -Path $script:Root4 -Force
|
|
211
219
|
script:Add-ProjectContent -Root $script:Root4
|
|
212
220
|
|
|
213
221
|
# Kit DIPASANG di npm-cache-like location (BUKAN di $script:Root4/.claude-kit)
|
|
214
|
-
$script:NpmCacheRoot = Join-Path $
|
|
222
|
+
$script:NpmCacheRoot = Join-Path $script:TempCanonical ("nodemod-test-{0}" -f ([guid]::NewGuid().ToString('N').Substring(0,8)))
|
|
215
223
|
$script:KitInNpmCache = Join-Path $script:NpmCacheRoot '@ojokesusu\lintasai'
|
|
216
224
|
$null = New-Item -ItemType Directory -Path $script:KitInNpmCache -Force
|
|
217
225
|
script:Copy-RealKit -Destination $script:KitInNpmCache
|
|
@@ -249,7 +257,7 @@ Describe "setup-pola-b.ps1 manifest creation" {
|
|
|
249
257
|
# Reuse pattern Branch 1 (traditional) – setelah setup sukses, manifest harus
|
|
250
258
|
# terbuat di .claude-kit/.install-manifest.json. Pakai fresh root supaya hash
|
|
251
259
|
# & state-nya independent dari describe lain.
|
|
252
|
-
$script:Root5 = Join-Path $
|
|
260
|
+
$script:Root5 = Join-Path $script:TempCanonical ("lintasAI-setup-test-manifest-{0}" -f ([guid]::NewGuid().ToString('N').Substring(0,8)))
|
|
253
261
|
$null = New-Item -ItemType Directory -Path $script:Root5 -Force
|
|
254
262
|
script:Add-ProjectContent -Root $script:Root5
|
|
255
263
|
$script:Kit5 = Join-Path $script:Root5 '.claude-kit'
|
package/uninstall.ps1
CHANGED
|
@@ -68,12 +68,13 @@ param(
|
|
|
68
68
|
)
|
|
69
69
|
|
|
70
70
|
# ---- Resolve $ProjectRoot early (param-driven, fallback to script location) ----
|
|
71
|
-
# Kalau user pass -ProjectRoot
|
|
72
|
-
# $
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
} else {
|
|
71
|
+
# Kalau user pass -ProjectRoot via param (npx wrapper / smoke test / CI), TRUST it sebagai
|
|
72
|
+
# ground truth -- $PSBoundParameters check supaya kita honor explicit param meski empty string.
|
|
73
|
+
# Kalau tidak di-supply, derive dari $PSScriptRoot (script ada di .claude-kit\, parent = project root).
|
|
74
|
+
if ($PSBoundParameters.ContainsKey('ProjectRoot') -and $ProjectRoot) {
|
|
76
75
|
$ProjectRoot = (Resolve-Path $ProjectRoot -ErrorAction Stop).Path
|
|
76
|
+
} else {
|
|
77
|
+
$ProjectRoot = Split-Path -Parent $PSScriptRoot
|
|
77
78
|
}
|
|
78
79
|
Write-Host "Root proyek : $ProjectRoot"
|
|
79
80
|
|
|
@@ -281,8 +282,12 @@ if ($schemaVersion -ne 1) {
|
|
|
281
282
|
# ---- Sanity check: project_root manifest match folder kit saat ini? ----
|
|
282
283
|
# Default HARD-FAIL untuk mencegah manifest dari project lain delete file di project ini.
|
|
283
284
|
# Override pakai -AllowProjectRootMismatch (mis. legitimate rename folder).
|
|
285
|
+
#
|
|
286
|
+
# GUARD: Kalau -ProjectRoot di-supply EXPLICIT via param (npx/CI/wrapper mode), TRUST it
|
|
287
|
+
# sebagai ground truth -- skip mismatch check (caller sudah explicit override).
|
|
284
288
|
$manifestProjectRoot = [string]$manifest.project_root
|
|
285
|
-
|
|
289
|
+
$projectRootSupplied = $PSBoundParameters.ContainsKey('ProjectRoot')
|
|
290
|
+
if (-not $projectRootSupplied -and $manifestProjectRoot -and $manifestProjectRoot -ne $ProjectRoot -and $manifestProjectRoot -ne '<PROJECT_ROOT>') {
|
|
286
291
|
Write-Host ''
|
|
287
292
|
if (-not $AllowProjectRootMismatch) {
|
|
288
293
|
Write-Host 'ABORT: Project root di manifest TIDAK match lokasi sekarang.' -ForegroundColor Red
|
|
@@ -305,6 +310,12 @@ if ($manifestProjectRoot -and $manifestProjectRoot -ne $ProjectRoot -and $manife
|
|
|
305
310
|
Write-Host ' Script pakai lokasi sekarang ($ProjectRoot) sebagai base.' -ForegroundColor Yellow
|
|
306
311
|
Write-Host ''
|
|
307
312
|
}
|
|
313
|
+
} elseif ($projectRootSupplied -and $manifestProjectRoot -and $manifestProjectRoot -ne $ProjectRoot -and $manifestProjectRoot -ne '<PROJECT_ROOT>') {
|
|
314
|
+
Write-Host ''
|
|
315
|
+
Write-Host 'INFO: -ProjectRoot di-supply explicit, manifest project_root override di-skip.' -ForegroundColor DarkGray
|
|
316
|
+
Write-Host " Manifest installed di : $manifestProjectRoot" -ForegroundColor DarkGray
|
|
317
|
+
Write-Host " Param -ProjectRoot : $ProjectRoot (ground truth)" -ForegroundColor DarkGray
|
|
318
|
+
Write-Host ''
|
|
308
319
|
}
|
|
309
320
|
|
|
310
321
|
# ---- Setup canonical project root (consumed by lib/safety.ps1 helpers) ----
|