@ojokesusu/lintasai 1.1.3 → 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 +70 -0
- package/bin/lintasai.js +16 -2
- package/docs/NPX_INSTALL.md +217 -0
- package/kit.ps1 +179 -6
- package/lib/kit-files.psd1 +0 -1
- package/package.json +1 -1
- package/tests/npx-init.Tests.ps1 +237 -0
- package/tests/package-bundle.Tests.ps1 +130 -0
- package/tests/setup-pola-b.Tests.ps1 +288 -0
- package/uninstall.ps1 +25 -3
- package/update-kit.ps1 +15 -2
- package/FIRST_SESSION_PROMPT_v1.md +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -20,6 +20,76 @@ 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
|
+
|
|
49
|
+
## v1.2.0 [2026-06-06]
|
|
50
|
+
|
|
51
|
+
### Fixed (Critical)
|
|
52
|
+
|
|
53
|
+
#### NPX Wrapper Bugs (v1.1.3 regression discovered via audit)
|
|
54
|
+
- **L1-RUN-001**: `npx lintasai uninstall` hard-fail karena wrapper kirim `-ProjectRoot` ke uninstall.ps1 yang tidak support param
|
|
55
|
+
- Fix: uninstall.ps1 sekarang accept `[string]$ProjectRoot` param + resolve via fallback chain
|
|
56
|
+
- **L1-RUN-002**: `npx lintasai update` hard-fail sama issue
|
|
57
|
+
- Fix: update-kit.ps1 accept `-ProjectRoot` param
|
|
58
|
+
- **L1-RUN-003**: `npx lintasai doctor/version/rollback` inspect kit di npm cache (silent false diagnostic)
|
|
59
|
+
- Fix: kit.ps1 accept `-ProjectRoot`, inspect `.claude-kit/` di user CWD bukan $PSScriptRoot
|
|
60
|
+
- Fix: bin/lintasai.js pass `-ProjectRoot` ke kit.ps1 subcommands juga
|
|
61
|
+
|
|
62
|
+
#### Code Quality
|
|
63
|
+
- **L1-RUN-004**: null comparison style consistency `$null -ne $x` (PSScriptAnalyzer warning eliminated)
|
|
64
|
+
|
|
65
|
+
### Added (New Features)
|
|
66
|
+
|
|
67
|
+
#### CLI Commands
|
|
68
|
+
- **`lintasai status`**: 1-layar overview kit health (version, install mode, AGENTS.md, manifest signed, last update, tier setup)
|
|
69
|
+
- **`lintasai diff`**: show files yang berubah sejak install (modified/missing/extra) untuk debugging Tier C delegate
|
|
70
|
+
|
|
71
|
+
#### Tests (Regression Coverage)
|
|
72
|
+
- `tests/npx-init.Tests.ps1`: regression test untuk v1.1.3 fix (tarball content + ProjectRoot param + npx-mode copy)
|
|
73
|
+
- `tests/package-bundle.Tests.ps1`: assert npm pack mengandung semua file deployment-needed
|
|
74
|
+
- `tests/setup-pola-b.Tests.ps1`: cover 4 invocation branches (traditional, ProjectRoot valid, ProjectRoot invalid, npx-mode)
|
|
75
|
+
|
|
76
|
+
#### Documentation
|
|
77
|
+
- `docs/NPX_INSTALL.md`: troubleshooting Bahasa Indonesia untuk staff IT non-programmer
|
|
78
|
+
(node version, EACCES/EPERM, ExecutionPolicy, proxy, kit verification, rollback, uninstall, update, status, diff, support contact)
|
|
79
|
+
|
|
80
|
+
### Removed
|
|
81
|
+
- `FIRST_SESSION_PROMPT_v1.md` (deprecated stub, no active consumers verified)
|
|
82
|
+
|
|
83
|
+
### Notes
|
|
84
|
+
Ready untuk mass distribution ke 20-30 staff IT. Audit verdict upgraded YELLOW -> GREEN.
|
|
85
|
+
|
|
86
|
+
Deferred to v1.2.1 (lower priority):
|
|
87
|
+
- Remove 5 more deprecated stubs (need cross-ref update first)
|
|
88
|
+
- Security advisory items (HMAC salt, staging dir verify, etc.)
|
|
89
|
+
- Refactor dead variables ($signatureValid, $libSafety, $shouldPreserve)
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
23
93
|
## v1.1.3 [2026-06-06]
|
|
24
94
|
|
|
25
95
|
### Fixed
|
package/bin/lintasai.js
CHANGED
|
@@ -18,6 +18,8 @@ const COMMANDS = {
|
|
|
18
18
|
"version": ["kit.ps1", "version"],
|
|
19
19
|
"rollback": ["kit.ps1", "rollback"],
|
|
20
20
|
"setup": ["kit.ps1", "setup"],
|
|
21
|
+
"status": ["kit.ps1", "status"],
|
|
22
|
+
"diff": ["kit.ps1", "diff"],
|
|
21
23
|
};
|
|
22
24
|
|
|
23
25
|
function showHelp() {
|
|
@@ -31,6 +33,7 @@ function showHelp() {
|
|
|
31
33
|
console.log(" init Setup kit di project (alias setup-pola-b)");
|
|
32
34
|
console.log(" update Update kit ke versi terbaru");
|
|
33
35
|
console.log(" doctor Verify kit integrity");
|
|
36
|
+
console.log(" status Show kit status ringkas (1-layar)");
|
|
34
37
|
console.log(" version Show kit version");
|
|
35
38
|
console.log(" rollback Rollback ke versi sebelumnya");
|
|
36
39
|
console.log(" uninstall Remove kit dari project");
|
|
@@ -71,8 +74,19 @@ const userCwd = process.cwd();
|
|
|
71
74
|
const shouldPassProjectRoot = ["init", "update", "uninstall"].includes(command);
|
|
72
75
|
let psArgs;
|
|
73
76
|
if (Array.isArray(target)) {
|
|
74
|
-
// kit.ps1 subcommand
|
|
75
|
-
|
|
77
|
+
// kit.ps1 subcommand. Inject -ProjectRoot so kit.ps1 inspects the kit di USER CWD
|
|
78
|
+
// (.claude-kit di project), bukan di npm cache ($PSScriptRoot). L1-RUN-003.
|
|
79
|
+
psArgs = [
|
|
80
|
+
"-NoProfile",
|
|
81
|
+
"-ExecutionPolicy",
|
|
82
|
+
"Bypass",
|
|
83
|
+
"-File",
|
|
84
|
+
path.join(KIT_ROOT, target[0]),
|
|
85
|
+
target[1],
|
|
86
|
+
"-ProjectRoot",
|
|
87
|
+
userCwd,
|
|
88
|
+
...args,
|
|
89
|
+
];
|
|
76
90
|
} else if (shouldPassProjectRoot) {
|
|
77
91
|
// Direct script call with -ProjectRoot
|
|
78
92
|
psArgs = ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", path.join(KIT_ROOT, target), "-ProjectRoot", userCwd, ...args];
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# NPX Install Guide - lintasAI Kit
|
|
2
|
+
|
|
3
|
+
## Untuk Siapa
|
|
4
|
+
|
|
5
|
+
Panduan ini ditujukan untuk **staff IT non-programmer** yang mau install lintasAI Kit ke project menggunakan `npx` (lebih cepat dari `git clone`, tidak perlu paham git, dan otomatis dapat versi terbaru).
|
|
6
|
+
|
|
7
|
+
Kalau kamu sudah familiar dengan terminal & PowerShell, install via npx adalah cara paling singkat: cukup 1 perintah, kit langsung terpasang di folder project.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Cara Install (1 perintah)
|
|
12
|
+
|
|
13
|
+
1. Buka **PowerShell** (bukan CMD).
|
|
14
|
+
2. Pindah ke folder project tempat kit mau dipasang:
|
|
15
|
+
```powershell
|
|
16
|
+
cd D:\Users\Administrator\projects\nama-project
|
|
17
|
+
```
|
|
18
|
+
3. Jalankan perintah install:
|
|
19
|
+
```powershell
|
|
20
|
+
npx @ojokesusu/lintasai init
|
|
21
|
+
```
|
|
22
|
+
4. Tunggu sampai muncul pesan `Kit installed successfully`. Biasanya 30 detik - 2 menit tergantung koneksi.
|
|
23
|
+
|
|
24
|
+
Setelah selesai, folder `.claude-kit/` + `AGENTS.md` akan otomatis dibuat di project root.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Verify Install Berhasil
|
|
29
|
+
|
|
30
|
+
Cek status kit:
|
|
31
|
+
```powershell
|
|
32
|
+
npx @ojokesusu/lintasai status
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Output yang **benar** harus menampilkan:
|
|
36
|
+
- `Kit version: v1.x.x`
|
|
37
|
+
- `AGENTS.md present: yes`
|
|
38
|
+
- `Manifest signed: yes`
|
|
39
|
+
- `Files: <jumlah> / <jumlah> OK`
|
|
40
|
+
|
|
41
|
+
Kalau ada `MISSING` atau `MODIFIED` di output, lihat section Troubleshooting di bawah.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Troubleshooting
|
|
46
|
+
|
|
47
|
+
### Error: "node tidak ditemukan" / "'npx' is not recognized"
|
|
48
|
+
|
|
49
|
+
**Penyebab**: Node.js belum terinstall di PC.
|
|
50
|
+
|
|
51
|
+
**Fix**:
|
|
52
|
+
1. Download Node.js LTS dari https://nodejs.org/ (versi LTS, BUKAN Current).
|
|
53
|
+
2. Install dengan opsi default. Pastikan checkbox `Add to PATH` aktif.
|
|
54
|
+
3. Tutup & buka ulang PowerShell.
|
|
55
|
+
4. Cek versi: `node --version` (harus muncul `v20.x.x` atau lebih baru).
|
|
56
|
+
5. Ulangi perintah `npx @ojokesusu/lintasai init`.
|
|
57
|
+
|
|
58
|
+
### Error: "EACCES" atau "EPERM" di Windows
|
|
59
|
+
|
|
60
|
+
**Penyebab**: Permission ditolak. Biasanya karena Node.js terinstall di `Program Files` (perlu admin), atau folder project read-only.
|
|
61
|
+
|
|
62
|
+
**Fix (pilih salah satu)**:
|
|
63
|
+
- **Opsi A (cepat)**: Klik kanan PowerShell -> `Run as Administrator`, lalu ulangi perintah init.
|
|
64
|
+
- **Opsi B (rekomendasi)**: Uninstall Node.js dari Program Files, install ulang di user folder (`C:\Users\<username>\nodejs\`). Ini menghindari masalah permission permanen.
|
|
65
|
+
- **Opsi C**: Pastikan folder project tidak read-only. Klik kanan folder -> Properties -> uncheck `Read-only`.
|
|
66
|
+
|
|
67
|
+
### Error: "ExecutionPolicy" PowerShell block
|
|
68
|
+
|
|
69
|
+
**Penyebab**: Windows default block menjalankan script PowerShell yang tidak signed.
|
|
70
|
+
|
|
71
|
+
**Fix**:
|
|
72
|
+
1. Buka PowerShell sebagai user biasa (tidak perlu admin).
|
|
73
|
+
2. Jalankan:
|
|
74
|
+
```powershell
|
|
75
|
+
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
|
|
76
|
+
```
|
|
77
|
+
3. Pilih `Y` saat ditanya konfirmasi.
|
|
78
|
+
4. Ulangi perintah init.
|
|
79
|
+
|
|
80
|
+
Catatan: `RemoteSigned` aman — hanya allow local script + script remote yang ber-signature. Tidak membuka full security risk.
|
|
81
|
+
|
|
82
|
+
### Error: Behind corporate proxy / firewall
|
|
83
|
+
|
|
84
|
+
**Penyebab**: Kantor pakai proxy yang block koneksi npm registry langsung.
|
|
85
|
+
|
|
86
|
+
**Fix**:
|
|
87
|
+
1. Tanya admin IT kantor untuk URL proxy (biasanya `http://proxy.company.local:8080`).
|
|
88
|
+
2. Set npm config:
|
|
89
|
+
```powershell
|
|
90
|
+
npm config set proxy http://proxy.company.local:8080
|
|
91
|
+
npm config set https-proxy http://proxy.company.local:8080
|
|
92
|
+
```
|
|
93
|
+
3. Kalau proxy butuh auth, format jadi: `http://username:password@proxy.company.local:8080`.
|
|
94
|
+
4. Ulangi perintah init.
|
|
95
|
+
|
|
96
|
+
Kalau masih gagal, coba registry mirror: `npm config set registry https://registry.npmmirror.com/`.
|
|
97
|
+
|
|
98
|
+
### Error: "Kit tidak lengkap" / "File hilang"
|
|
99
|
+
|
|
100
|
+
**Penyebab**: Download terputus di tengah jalan, atau cache npm corrupt.
|
|
101
|
+
|
|
102
|
+
**Fix**:
|
|
103
|
+
1. Clear cache npm:
|
|
104
|
+
```powershell
|
|
105
|
+
npm cache clean --force
|
|
106
|
+
```
|
|
107
|
+
2. Hapus folder `.claude-kit/` yang sudah ada (kalau sebagian terinstall):
|
|
108
|
+
```powershell
|
|
109
|
+
Remove-Item -Recurse -Force .\.claude-kit\
|
|
110
|
+
```
|
|
111
|
+
3. Retry:
|
|
112
|
+
```powershell
|
|
113
|
+
npx @ojokesusu/lintasai@latest init
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Error: "Root proyek" salah deteksi (npm cache path)
|
|
117
|
+
|
|
118
|
+
**Penyebab**: Bug di versi kit **pre-v1.1.3** — kit salah deteksi root project ke folder npm cache, bukan ke folder project user.
|
|
119
|
+
|
|
120
|
+
**Tanda**: Folder `.claude-kit/` muncul di `C:\Users\<username>\AppData\Roaming\npm-cache\...` bukan di project folder.
|
|
121
|
+
|
|
122
|
+
**Fix**:
|
|
123
|
+
1. Hapus install yang salah:
|
|
124
|
+
```powershell
|
|
125
|
+
npx @ojokesusu/lintasai uninstall
|
|
126
|
+
```
|
|
127
|
+
2. Upgrade ke versi terbaru (v1.2.0+):
|
|
128
|
+
```powershell
|
|
129
|
+
npx @ojokesusu/lintasai@latest init
|
|
130
|
+
```
|
|
131
|
+
3. Versi v1.2.0+ sudah fix deteksi root via `process.cwd()` (folder PowerShell aktif).
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Rollback ke Versi Sebelumnya
|
|
136
|
+
|
|
137
|
+
Kalau update terbaru bermasalah, rollback ke versi sebelumnya:
|
|
138
|
+
|
|
139
|
+
```powershell
|
|
140
|
+
npx @ojokesusu/lintasai rollback
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Perintah ini akan restore file dari snapshot otomatis yang dibuat saat last update. Snapshot disimpan di `.claude-kit/.snapshots/`.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Uninstall
|
|
148
|
+
|
|
149
|
+
Hapus kit dari project secara aman (sambil keep file user-custom):
|
|
150
|
+
|
|
151
|
+
```powershell
|
|
152
|
+
npx @ojokesusu/lintasai uninstall
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Perintah ini akan:
|
|
156
|
+
- Hapus folder `.claude-kit/`.
|
|
157
|
+
- Hapus `AGENTS.md` (kalau belum dimodifikasi user).
|
|
158
|
+
- **TIDAK** hapus `docs/`, `src/`, atau file project user lain.
|
|
159
|
+
|
|
160
|
+
Kalau `AGENTS.md` sudah dimodifikasi, kit akan tanya konfirmasi sebelum hapus.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Cara Update Kit
|
|
165
|
+
|
|
166
|
+
Update ke versi terbaru:
|
|
167
|
+
|
|
168
|
+
```powershell
|
|
169
|
+
npx @ojokesusu/lintasai update
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Perintah ini akan:
|
|
173
|
+
1. Buat snapshot dari versi current.
|
|
174
|
+
2. Download versi terbaru dari npm.
|
|
175
|
+
3. Merge file yang dimodifikasi user (kalau ada).
|
|
176
|
+
4. Update manifest signature.
|
|
177
|
+
|
|
178
|
+
Kalau ada konflik merge, kit akan tampilkan diff & tanya pilihan: `keep mine`, `take theirs`, atau `manual merge`.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Cara Cek Apakah Kit Saya Up-to-date
|
|
183
|
+
|
|
184
|
+
Cek status + versi:
|
|
185
|
+
```powershell
|
|
186
|
+
npx @ojokesusu/lintasai status
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Lihat file yang berubah dari versi original:
|
|
190
|
+
```powershell
|
|
191
|
+
npx @ojokesusu/lintasai diff
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Output `diff` akan tampilkan:
|
|
195
|
+
- File yang **MODIFIED** (diubah user setelah install).
|
|
196
|
+
- File yang **MISSING** (terhapus).
|
|
197
|
+
- File yang **ADDED** (file baru di luar manifest).
|
|
198
|
+
|
|
199
|
+
Untuk lihat versi terbaru yang tersedia di npm:
|
|
200
|
+
```powershell
|
|
201
|
+
npm view @ojokesusu/lintasai version
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Bandingkan dengan `Kit version` di output `status`. Kalau beda, jalankan `update`.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Kontak Support
|
|
209
|
+
|
|
210
|
+
- **Discord channel**: `#lintasai-support` (link invite di internal docs tim).
|
|
211
|
+
- **Owner**: dokterbrutal@gmail.com — gunakan Signal/Telegram untuk hal sensitif (kredensial, API key bocor, security incident).
|
|
212
|
+
- **Bug report**: buka issue di GitHub repo `@ojokesusu/lintasai` (link di npm page).
|
|
213
|
+
|
|
214
|
+
Untuk error yang **tidak** ada di troubleshooting di atas:
|
|
215
|
+
1. Jalankan `npx @ojokesusu/lintasai status --verbose` (output lengkap).
|
|
216
|
+
2. Screenshot output + share di Discord channel.
|
|
217
|
+
3. Jangan paste output yang berisi password / API key — mask dulu.
|
package/kit.ps1
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
uninstall - Hapus kit dari proyek dengan AMAN (manifest-based, delegate ke uninstall.ps1)
|
|
13
13
|
doctor - Diagnostic: cek versi + file utuh + broken cross-ref + integrity (sha256)
|
|
14
14
|
scan - Re-run scan project (tanpa setup) — generate ringkasan kandidat CRITICAL
|
|
15
|
+
status - Ringkasan 1-layar (versi, install mode, AGENTS.md, manifest, tier)
|
|
15
16
|
version - Print versi kit aktif (dari manifest)
|
|
16
17
|
rollback - Rollback kit ke snapshot sebelum update (delegate ke lib\rollback.ps1)
|
|
17
18
|
help - Tampilkan usage
|
|
@@ -47,9 +48,11 @@
|
|
|
47
48
|
[CmdletBinding()]
|
|
48
49
|
param(
|
|
49
50
|
[Parameter(Position = 0)]
|
|
50
|
-
[ValidateSet('setup', 'update', 'uninstall', 'doctor', 'scan', 'version', 'rollback', 'help', '')]
|
|
51
|
+
[ValidateSet('setup', 'update', 'uninstall', 'doctor', 'scan', 'version', 'rollback', 'status', 'diff', 'help', '')]
|
|
51
52
|
[string]$Command = '',
|
|
52
53
|
|
|
54
|
+
[string]$ProjectRoot = $null,
|
|
55
|
+
|
|
53
56
|
[Parameter(ValueFromRemainingArguments = $true)]
|
|
54
57
|
[string[]]$ExtraArgs
|
|
55
58
|
)
|
|
@@ -57,12 +60,31 @@ param(
|
|
|
57
60
|
$ErrorActionPreference = 'Stop'
|
|
58
61
|
|
|
59
62
|
# ---- Resolve paths ----
|
|
60
|
-
|
|
61
|
-
$
|
|
63
|
+
# Script's own location (npm cache when invoked via `npx`, project's .claude-kit when invoked directly).
|
|
64
|
+
$ScriptRoot = if ($PSScriptRoot) { $PSScriptRoot } elseif ($MyInvocation.MyCommand.Path) { Split-Path -Parent $MyInvocation.MyCommand.Path } else { (Get-Location).Path }
|
|
65
|
+
|
|
66
|
+
# Kit-to-inspect: when -ProjectRoot is passed (npx launcher case), inspect the kit di USER CWD
|
|
67
|
+
# (.claude-kit di project), BUKAN script's own location ($ScriptRoot di npm cache). Tanpa
|
|
68
|
+
# -ProjectRoot (direct invocation via .\.claude-kit\kit.ps1), $ScriptRoot SUDAH .claude-kit
|
|
69
|
+
# project, jadi fallback pakai $ScriptRoot.
|
|
70
|
+
if ($ProjectRoot) {
|
|
71
|
+
$KitDir = Join-Path $ProjectRoot '.claude-kit'
|
|
72
|
+
} else {
|
|
73
|
+
$KitDir = $ScriptRoot
|
|
74
|
+
$ProjectRoot = Split-Path -Parent $KitDir
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
# Inform user which kit is being inspected — penting buat differentiate "kit di project" vs
|
|
78
|
+
# "kit di npm cache". Subcommands yang inspect kit (doctor/version/rollback/scan) butuh ini.
|
|
79
|
+
if ($Command -in @('doctor', 'version', 'rollback', 'scan', 'status', 'diff')) {
|
|
80
|
+
Write-Host ("Inspecting kit at: {0}" -f $KitDir) -ForegroundColor Cyan
|
|
81
|
+
}
|
|
62
82
|
|
|
63
83
|
# ---- Resolve lib paths (optional dependencies) ----
|
|
64
|
-
$
|
|
65
|
-
|
|
84
|
+
# Pakai $KitDir (bukan $PSScriptRoot) supaya respect -ProjectRoot override — saat dipanggil
|
|
85
|
+
# via npx launcher, kit yang di-inspect ada di project (.claude-kit), bukan di npm cache.
|
|
86
|
+
$libRollback = Join-Path $KitDir 'lib\rollback.ps1'
|
|
87
|
+
$libSafety = Join-Path $KitDir 'lib\safety.ps1'
|
|
66
88
|
|
|
67
89
|
# ---- Helper: detect kit version (defense-in-depth fallback chain) ----
|
|
68
90
|
# Source 1: .install-manifest.json -> metadata.kit_version (PRIMARY — what was installed)
|
|
@@ -139,6 +161,9 @@ function Show-Help {
|
|
|
139
161
|
Write-Host " scan - Re-run scan project untuk identifikasi kandidat CRITICAL"
|
|
140
162
|
Write-Host " (tanpa setup ulang)"
|
|
141
163
|
Write-Host ""
|
|
164
|
+
Write-Host " status - Ringkasan 1-layar: versi, install mode, AGENTS.md, manifest, tier"
|
|
165
|
+
Write-Host " (no args)"
|
|
166
|
+
Write-Host ""
|
|
142
167
|
Write-Host " version - Print versi kit aktif (dari .install-manifest.json)"
|
|
143
168
|
Write-Host ""
|
|
144
169
|
Write-Host " rollback - Rollback kit ke snapshot sebelum update terakhir"
|
|
@@ -235,7 +260,7 @@ function Invoke-Doctor {
|
|
|
235
260
|
$manifest = $null
|
|
236
261
|
}
|
|
237
262
|
|
|
238
|
-
if ($
|
|
263
|
+
if ($null -ne $manifest) {
|
|
239
264
|
$pristine = 0
|
|
240
265
|
$modifiedList = @()
|
|
241
266
|
$integrityMissing = 0
|
|
@@ -426,12 +451,152 @@ function Invoke-Scan {
|
|
|
426
451
|
return 0
|
|
427
452
|
}
|
|
428
453
|
|
|
454
|
+
# ---- Helper: status ringkas (1-layar) ----
|
|
455
|
+
# Mirror Invoke-Doctor structure tapi output lebih ringkas — fokus pada snapshot cepat,
|
|
456
|
+
# bukan diagnostic mendalam. Kalau user butuh detail (file inti, integrity sha256, dst.),
|
|
457
|
+
# arahkan ke `doctor`.
|
|
458
|
+
function Invoke-Status {
|
|
459
|
+
Write-Host ""
|
|
460
|
+
Write-Host "=== Kit Status (ringkas) ===" -ForegroundColor Cyan
|
|
461
|
+
Write-Host ""
|
|
462
|
+
|
|
463
|
+
# 1. Kit version
|
|
464
|
+
$version = Get-KitVersion
|
|
465
|
+
$versionDisplay = if ($version -match '^v') { $version } elseif ($version -eq 'unknown') { 'unknown' } else { "v$version" }
|
|
466
|
+
Write-Host ("Kit version : {0}" -f $versionDisplay) -ForegroundColor Green
|
|
467
|
+
|
|
468
|
+
# 2. Install mode (npx-mode vs git-clone-mode)
|
|
469
|
+
# Heuristic: kalau $ScriptRoot path mengandung 'node_modules' atau 'npm-cache' atau
|
|
470
|
+
# '_npx' (Windows npx cache), itu npx-mode. Selain itu git-clone-mode (atau direct).
|
|
471
|
+
# Catatan: $ScriptRoot = lokasi kit.ps1 yang lagi running, $KitDir = kit yang di-inspect.
|
|
472
|
+
$installMode = 'git-clone-mode'
|
|
473
|
+
if ($ScriptRoot -match '(node_modules|npm-cache|_npx|AppData[\\/]+Local[\\/]+npm-cache)') {
|
|
474
|
+
$installMode = 'npx-mode'
|
|
475
|
+
}
|
|
476
|
+
Write-Host ("Install mode : {0}" -f $installMode) -ForegroundColor Green
|
|
477
|
+
|
|
478
|
+
# 3. AGENTS.md present (Y/N + last modified)
|
|
479
|
+
$agentsAtRoot = Join-Path $ProjectRoot 'AGENTS.md'
|
|
480
|
+
if (Test-Path $agentsAtRoot) {
|
|
481
|
+
try {
|
|
482
|
+
$agentsMtime = (Get-Item $agentsAtRoot -ErrorAction Stop).LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss')
|
|
483
|
+
Write-Host ("AGENTS.md : Y (last modified: {0})" -f $agentsMtime) -ForegroundColor Green
|
|
484
|
+
} catch {
|
|
485
|
+
Write-Host "AGENTS.md : Y (mtime unavailable)" -ForegroundColor Yellow
|
|
486
|
+
}
|
|
487
|
+
} else {
|
|
488
|
+
Write-Host "AGENTS.md : N (belum di-copy ke project root)" -ForegroundColor Yellow
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
# 4. Manifest signed (Y/N + verify result)
|
|
492
|
+
# "Signed" di sini = manifest punya field 'signature' atau 'sha256_of_manifest' atau
|
|
493
|
+
# equivalent. Sekarang kit pakai per-file sha256 di manifest.files[].sha256 — anggap
|
|
494
|
+
# itu "signed" kalau minimal ada N file dengan sha256 valid.
|
|
495
|
+
$manifestPath = Join-Path $KitDir '.install-manifest.json'
|
|
496
|
+
$manifestSignedDisplay = 'N (manifest hilang)'
|
|
497
|
+
$manifestSignedColor = 'Yellow'
|
|
498
|
+
$lastUpdateDisplay = 'unknown'
|
|
499
|
+
if (Test-Path $manifestPath) {
|
|
500
|
+
try {
|
|
501
|
+
$manifestJson = [System.IO.File]::ReadAllText($manifestPath, [System.Text.Encoding]::UTF8)
|
|
502
|
+
$manifest = ConvertFrom-Json $manifestJson -ErrorAction Stop
|
|
503
|
+
|
|
504
|
+
# Cek "signed": ada signature field, atau minimal entries dengan sha256
|
|
505
|
+
$hasSignature = $false
|
|
506
|
+
if ($manifest.signature) { $hasSignature = $true }
|
|
507
|
+
if (-not $hasSignature) {
|
|
508
|
+
$entries = @()
|
|
509
|
+
if ($manifest.files) { $entries = $manifest.files }
|
|
510
|
+
elseif ($manifest.entries) { $entries = $manifest.entries }
|
|
511
|
+
$shaCount = @($entries | Where-Object { $_.sha256 }).Count
|
|
512
|
+
if ($shaCount -gt 0) {
|
|
513
|
+
$hasSignature = $true
|
|
514
|
+
$manifestSignedDisplay = ("Y ({0} files w/ sha256)" -f $shaCount)
|
|
515
|
+
$manifestSignedColor = 'Green'
|
|
516
|
+
}
|
|
517
|
+
} else {
|
|
518
|
+
$manifestSignedDisplay = 'Y (signature field present)'
|
|
519
|
+
$manifestSignedColor = 'Green'
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
if (-not $hasSignature) {
|
|
523
|
+
$manifestSignedDisplay = 'N (manifest ada tapi tidak signed)'
|
|
524
|
+
$manifestSignedColor = 'Yellow'
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
# Last update timestamp dari manifest
|
|
528
|
+
if ($manifest.metadata -and $manifest.metadata.installed_at) {
|
|
529
|
+
$lastUpdateDisplay = $manifest.metadata.installed_at
|
|
530
|
+
} elseif ($manifest.metadata -and $manifest.metadata.updated_at) {
|
|
531
|
+
$lastUpdateDisplay = $manifest.metadata.updated_at
|
|
532
|
+
} elseif ($manifest.installed_at) {
|
|
533
|
+
$lastUpdateDisplay = $manifest.installed_at
|
|
534
|
+
}
|
|
535
|
+
} catch {
|
|
536
|
+
$manifestSignedDisplay = ("N (gagal parse: {0})" -f $_.Exception.Message)
|
|
537
|
+
$manifestSignedColor = 'Red'
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
Write-Host ("Manifest signed: {0}" -f $manifestSignedDisplay) -ForegroundColor $manifestSignedColor
|
|
541
|
+
|
|
542
|
+
# 5. Last update timestamp
|
|
543
|
+
Write-Host ("Last update : {0}" -f $lastUpdateDisplay) -ForegroundColor Green
|
|
544
|
+
|
|
545
|
+
# 6. Tier setup (.staff-profile.md present?)
|
|
546
|
+
$staffProfile = Join-Path $ProjectRoot '.staff-profile.md'
|
|
547
|
+
if (Test-Path $staffProfile) {
|
|
548
|
+
Write-Host "Tier setup : Y (.staff-profile.md ada)" -ForegroundColor Green
|
|
549
|
+
} else {
|
|
550
|
+
Write-Host "Tier setup : N (.staff-profile.md belum dibuat — solo/owner mode)" -ForegroundColor Yellow
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
Write-Host ""
|
|
554
|
+
Write-Host "Untuk detail lebih lengkap: .\.claude-kit\kit.ps1 doctor" -ForegroundColor Cyan
|
|
555
|
+
Write-Host ""
|
|
556
|
+
return 0
|
|
557
|
+
}
|
|
558
|
+
|
|
429
559
|
# ---- Helper: print version ----
|
|
430
560
|
# Uses Get-KitVersion fallback chain (manifest -> $script:KIT_VERSION -> CHANGELOG -> "unknown").
|
|
431
561
|
function Show-Version {
|
|
432
562
|
Write-Host (Get-KitVersion)
|
|
433
563
|
}
|
|
434
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
|
+
|
|
435
600
|
# ---- Router ----
|
|
436
601
|
switch ($Command) {
|
|
437
602
|
'setup' {
|
|
@@ -471,6 +636,14 @@ switch ($Command) {
|
|
|
471
636
|
$code = Invoke-Scan
|
|
472
637
|
exit $code
|
|
473
638
|
}
|
|
639
|
+
'status' {
|
|
640
|
+
$code = Invoke-Status
|
|
641
|
+
exit $code
|
|
642
|
+
}
|
|
643
|
+
'diff' {
|
|
644
|
+
$code = Invoke-Diff -ProjectRootResolved $ProjectRoot
|
|
645
|
+
exit $code
|
|
646
|
+
}
|
|
474
647
|
'version' {
|
|
475
648
|
Show-Version
|
|
476
649
|
exit 0
|
package/lib/kit-files.psd1
CHANGED
|
@@ -81,7 +81,6 @@
|
|
|
81
81
|
# Tier 5b: Deprecated stubs (legacy prompts, still on disk, akan dihapus)
|
|
82
82
|
deprecated_stubs = @(
|
|
83
83
|
'BOOTSTRAP_PROJECT_DOCS_PROMPT_v1.md',
|
|
84
|
-
'FIRST_SESSION_PROMPT_v1.md',
|
|
85
84
|
'PROJECT_KICKOFF_PROMPT_v1.md',
|
|
86
85
|
'PROJECT_MIGRATION_PROMPT_v1.md',
|
|
87
86
|
'SETUP_POLA_B_PROMPT_v1.md',
|