@ojokesusu/lintasai 1.1.2

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 (86) hide show
  1. package/.github/workflows/publish-npm.yml +40 -0
  2. package/.github/workflows/validate.yml +93 -0
  3. package/AUDIT_POST_SETUP_PROMPT_v1.md +280 -0
  4. package/BOOTSTRAP_PROJECT_DOCS_PROMPT_v1.md +3 -0
  5. package/CHANGELOG.md +313 -0
  6. package/CLAUDE_universal_v1.md +1021 -0
  7. package/CONTRIBUTING.md +101 -0
  8. package/FIRST_SESSION_PROMPT_v1.md +7 -0
  9. package/JALANKAN_KIT.md +188 -0
  10. package/LICENSE +21 -0
  11. package/MULAI_DI_SINI.md +145 -0
  12. package/PROJECT_KICKOFF_PROMPT_v1.md +3 -0
  13. package/PROJECT_LIFECYCLE_PROMPT_v1.md +536 -0
  14. package/PROJECT_MIGRATION_PROMPT_v1.md +3 -0
  15. package/README.md +505 -0
  16. package/SETUP_POLA_B_PROMPT_v1.md +5 -0
  17. package/SPLIT_REPO_MIGRATION_PROMPT_v1.md +485 -0
  18. package/TEAM_ROLLOUT_GUIDE_v1.md +172 -0
  19. package/UPDATE_DOCS_PROMPT_v1.md +3 -0
  20. package/UPDATE_KIT_PROMPT_v1.md +213 -0
  21. package/bin/lintasai.js +81 -0
  22. package/docs/SIGNED_RELEASE.md +162 -0
  23. package/install-windows.ps1 +225 -0
  24. package/kit.ps1 +508 -0
  25. package/lib/agents-md.ps1 +174 -0
  26. package/lib/git-helpers.ps1 +104 -0
  27. package/lib/kit-files.psd1 +133 -0
  28. package/lib/manifest-signing.ps1 +65 -0
  29. package/lib/manifest.ps1 +267 -0
  30. package/lib/rollback.ps1 +241 -0
  31. package/lib/safety.ps1 +193 -0
  32. package/lib/template-deploy.ps1 +242 -0
  33. package/lib/version-detect.ps1 +161 -0
  34. package/package.json +36 -0
  35. package/setup-pola-b.ps1 +687 -0
  36. package/templates/ANALOGI_LIBRARY.md +7 -0
  37. package/templates/CLAUDE_TEAM_GUIDE.md +505 -0
  38. package/templates/CROSS_REPO_TYPES_PIPELINE.md +473 -0
  39. package/templates/DB_SCHEMA_SCAN_PROMPT.md +194 -0
  40. package/templates/DISCORD_BOT_INTEGRATION.md +187 -0
  41. package/templates/GLOSSARY_NON_PROGRAMMER.md +361 -0
  42. package/templates/INDEX.md +157 -0
  43. package/templates/MCP_SETUP.md +1145 -0
  44. package/templates/MIGRATE_TO_SUBFOLDER_PROMPT_v1.md +220 -0
  45. package/templates/ONBOARDING.md +172 -0
  46. package/templates/PROJECT_STARTER_TEMPLATES.md +264 -0
  47. package/templates/PROMPT_LIBRARY.md +790 -0
  48. package/templates/RLS_SETUP_PROMPT.md +167 -0
  49. package/templates/SECURITY_INCIDENT_PLAYBOOK.md +191 -0
  50. package/templates/SPLIT_REPO_AGENTS_TEMPLATES.md +32 -0
  51. package/templates/SPLIT_REPO_NON_PROGRAMMER_PROMPTS.md +604 -0
  52. package/templates/SPLIT_REPO_TOOLS_SETUP.md +388 -0
  53. package/templates/STACK_DETECTION_PATTERN.md +261 -0
  54. package/templates/STACK_GUIDE.md +564 -0
  55. package/templates/STACK_MIGRATION_GUIDE.md +154 -0
  56. package/templates/STACK_VERSIONS.md +31 -0
  57. package/templates/UPDATE_GUIDE.md +246 -0
  58. package/templates/_EXAMPLE.md +110 -0
  59. package/templates/_PATTERNS.md +173 -0
  60. package/templates/architecture.md +180 -0
  61. package/templates/architecture_auto.md +61 -0
  62. package/templates/decisions/README.md +108 -0
  63. package/templates/decisions/_TEMPLATE.md +84 -0
  64. package/templates/feature-flags-advanced.md +171 -0
  65. package/templates/github/CODEOWNERS.template +61 -0
  66. package/templates/github/GENERATE_TYPES_SCRIPT.md +77 -0
  67. package/templates/github/PUBLISH_SHARED_WORKFLOW.yml +52 -0
  68. package/templates/github/RECEIVE_BACKEND_UPDATE.yml +106 -0
  69. package/templates/github/RENOVATE_FRONTEND.json +28 -0
  70. package/templates/github/TRIGGER_FRONTEND_UPDATE.yml +29 -0
  71. package/templates/github/pull_request_template.md +44 -0
  72. package/templates/github/scripts/ai-review.js +153 -0
  73. package/templates/github/workflows/ai-review.yml +61 -0
  74. package/templates/github/workflows/backup-schemas.yml +169 -0
  75. package/templates/glossary.md +110 -0
  76. package/templates/split-agents/BACKEND.md +149 -0
  77. package/templates/split-agents/FRONTEND.md +141 -0
  78. package/templates/split-agents/SHARED.md +82 -0
  79. package/templates/split-agents/TOOLS.md +77 -0
  80. package/tests/Run-Tests.ps1 +19 -0
  81. package/tests/lib-safety.Tests.ps1 +66 -0
  82. package/tests/rollback.Tests.ps1 +66 -0
  83. package/tests/uninstall.Tests.ps1 +265 -0
  84. package/tests/update-kit.Tests.ps1 +78 -0
  85. package/uninstall.ps1 +794 -0
  86. package/update-kit.ps1 +907 -0
@@ -0,0 +1,687 @@
1
+ <#
2
+ .SYNOPSIS
3
+ setup-pola-b.ps1 - Setup Pola B di root proyek (kit embed sebagai subfolder)
4
+ .DESCRIPTION
5
+ Asumsi: kamu sudah extract zip kit ini jadi <proyek>\.claude-kit\, lalu jalanin
6
+ script ini dari folder <proyek>\.claude-kit\.
7
+
8
+ Script ini ORCHESTRATOR — heavy-lifting di delegate ke lib/*.ps1:
9
+ - lib\manifest.ps1 : Initialize/Add/Save manifest (.install-manifest.json)
10
+ - lib\template-deploy.ps1 : Copy template + placeholder substitution
11
+ - lib\git-helpers.ps1 : Strip .git + Unblock MOTW
12
+ - lib\agents-md.ps1 : Deploy AGENTS.md (template fill + backup)
13
+ - lib\version-detect.ps1 : Parse versi kit dari CHANGELOG.md
14
+ - lib\manifest-signing.ps1 : HMAC sign manifest (loaded via Save-Manifest)
15
+ - lib\safety.ps1 : Path safety helpers
16
+
17
+ Tugas orchestrator:
18
+ 1. Project root validation + nested-extract detection
19
+ 2. Interactive prompts (popup CLAUDE.md, nama, repo, AGENTS.md overwrite)
20
+ 3. Verifikasi file inti kit ada (via lib\kit-files.psd1)
21
+ 4. Call lib functions untuk actual deploy
22
+ 5. Final summary report
23
+
24
+ TIDAK install ke ~/.claude/ (itu Pola Global, pakai install-windows.ps1).
25
+ .PARAMETER Force
26
+ Timpa AGENTS.md yang sudah ada (backup otomatis ke .backup-<timestamp>).
27
+ Saat -Force aktif, prompt opsional Nama/URL repo di-skip (placeholder default dipakai).
28
+ .PARAMETER DryRun
29
+ Tampilkan rencana aksi tanpa nulis/copy file apapun.
30
+ .NOTES
31
+ Versi : 2.0 (orchestrator refactor, 2026-06-06)
32
+ Run : powershell -ExecutionPolicy Bypass -File .\setup-pola-b.ps1
33
+ Atau : cd <proyek>\.claude-kit; .\setup-pola-b.ps1
34
+ Lebih ringkas: .\.claude-kit\kit.ps1 setup
35
+ #>
36
+
37
+ [CmdletBinding()]
38
+ param(
39
+ [switch]$Force,
40
+ [switch]$DryRun,
41
+ [switch]$SkipTeamFiles
42
+ )
43
+
44
+ $ErrorActionPreference = 'Stop'
45
+
46
+ # ---- Resolve folder kit (tempat script ini berada) ----
47
+ $KitDir = if ($PSScriptRoot) { $PSScriptRoot } elseif ($MyInvocation.MyCommand.Path) { Split-Path -Parent $MyInvocation.MyCommand.Path } else { (Get-Location).Path }
48
+
49
+ # ---- Dot-source library helpers (heavy-lifting) ----
50
+ # Order penting: agents-md.ps1 dot-source SEBELUM manifest.ps1.
51
+ # agents-md.ps1 punya guard `if ($script:__lintasAI_AgentsMdLoaded)` (anti-redefine).
52
+ # manifest.ps1 set `Set-StrictMode -Version Latest` yang kebawa ke caller scope —
53
+ # strict mode reject access ke variable yang belum di-set. Kalau order kebalik,
54
+ # guard agents-md crash karena `$script:__lintasAI_AgentsMdLoaded` belum ada.
55
+ $script:__lintasAI_AgentsMdLoaded = $null
56
+ . (Join-Path $KitDir 'lib\safety.ps1')
57
+ . (Join-Path $KitDir 'lib\agents-md.ps1')
58
+ . (Join-Path $KitDir 'lib\template-deploy.ps1')
59
+ . (Join-Path $KitDir 'lib\git-helpers.ps1')
60
+ . (Join-Path $KitDir 'lib\version-detect.ps1')
61
+ . (Join-Path $KitDir 'lib\manifest.ps1')
62
+ # manifest-signing.ps1 di-load on-demand oleh Save-Manifest (lib\manifest.ps1)
63
+
64
+ # ---- Deteksi NESTED extract (zip extract jadi folder dalam folder) ----
65
+ # Skenario: Windows Explorer "Extract All" sering bikin .claude-kit\<kit-folder>\...
66
+ $kitFolderName = Split-Path -Leaf $KitDir
67
+ $parentDir = Split-Path -Parent $KitDir
68
+ $parentFolderName = Split-Path -Leaf $parentDir
69
+
70
+ if ($kitFolderName -ne '.claude-kit' -and $parentFolderName -eq '.claude-kit') {
71
+ Write-Host "DETEKSI: Kit ter-extract NESTED - script ada di '$kitFolderName' di dalam '.claude-kit'." -ForegroundColor Yellow
72
+ Write-Host " Ini biasa terjadi kalau extract pakai Windows Explorer (Extract All)." -ForegroundColor Yellow
73
+ Write-Host ""
74
+
75
+ if (-not $Force -and -not $DryRun) {
76
+ # Wrap Read-Host di try/catch — gracefully handle NonInteractive shell.
77
+ # Default ke 'N' (abort, jangan auto-flatten destruktif tanpa user consent).
78
+ $autoFix = 'N'
79
+ try {
80
+ $autoFix = Read-Host "Mau aku auto-flatten? (pindahkan isi '$kitFolderName' ke '.claude-kit', hapus folder kosong) [Y/N]"
81
+ } catch {
82
+ Write-Host "INFO: Shell NonInteractive terdeteksi. Auto-flatten butuh konfirmasi user — abort." -ForegroundColor Yellow
83
+ Write-Host " Jalankan di PowerShell window untuk pilih Y/N, atau pakai -Force untuk auto-yes." -ForegroundColor Yellow
84
+ $autoFix = 'N'
85
+ }
86
+ if ($autoFix -notmatch '^[Yy]') {
87
+ Write-Host "Dibatalkan. Untuk fix manual:" -ForegroundColor Yellow
88
+ Write-Host " 1. Pindahkan SEMUA isi '$KitDir' ke parent '$parentDir'." -ForegroundColor Yellow
89
+ Write-Host " 2. Hapus folder kosong '$KitDir'." -ForegroundColor Yellow
90
+ Write-Host " 3. Jalankan ulang setup-pola-b.ps1 dari '$parentDir\setup-pola-b.ps1'." -ForegroundColor Yellow
91
+ exit 1
92
+ }
93
+ }
94
+
95
+ if ($DryRun) {
96
+ Write-Host "[DRY] Akan flatten: pindahkan '$KitDir\*' ke '$parentDir\', hapus '$KitDir'." -ForegroundColor Yellow
97
+ Write-Host "[DRY] Setelah flatten, validasi 13 file inti + setup AGENTS.md akan jalan dari '$parentDir'." -ForegroundColor Yellow
98
+ Write-Host ""
99
+ Write-Host "Mode DRY-RUN: berhenti setelah preview nested. Jalankan ulang tanpa -DryRun untuk eksekusi sungguhan." -ForegroundColor Cyan
100
+ exit 0
101
+ } else {
102
+ try {
103
+ Write-Host "FLATTEN: $KitDir\* -> $parentDir\" -ForegroundColor Cyan
104
+ Get-ChildItem -Path $KitDir -Force | Move-Item -Destination $parentDir -Force
105
+ Remove-Item -Path $KitDir -Recurse -Force
106
+ Write-Host "OK Flatten selesai." -ForegroundColor Green
107
+ $KitDir = $parentDir
108
+ $kitFolderName = Split-Path -Leaf $KitDir
109
+ Write-Host ""
110
+ } catch {
111
+ Write-Host "GAGAL flatten: $_" -ForegroundColor Red
112
+ Write-Host " Fix manual: pindahkan isi $KitDir ke parent, hapus folder kosong." -ForegroundColor Red
113
+ $sisaFiles = Get-ChildItem -Path $KitDir -Force -ErrorAction SilentlyContinue
114
+ if ($sisaFiles) {
115
+ Write-Host " File yang masih di ${KitDir}:" -ForegroundColor Yellow
116
+ $sisaFiles | ForEach-Object { Write-Host " $($_.Name)" -ForegroundColor Yellow }
117
+ }
118
+ exit 1
119
+ }
120
+ }
121
+ }
122
+
123
+ # ---- Validasi: kit harus berada di subfolder bernama .claude-kit ----
124
+ if ($kitFolderName -ne '.claude-kit') {
125
+ Write-Host "PERINGATAN: Folder kit ini bernama '$kitFolderName', bukan '.claude-kit'." -ForegroundColor Yellow
126
+ Write-Host " Pola B mengasumsikan kit ada di '<proyek>\.claude-kit\'." -ForegroundColor Yellow
127
+ Write-Host " Aku tetap lanjut, tapi AGENTS.md akan rujuk path '.\$kitFolderName\'" -ForegroundColor Yellow
128
+ Write-Host " - kalau mau path standar, rename folder ini jadi '.claude-kit' dulu." -ForegroundColor Yellow
129
+ Write-Host ""
130
+ }
131
+
132
+ # ---- Resolve root proyek (parent dari folder kit) ----
133
+ $ProjectRoot = Split-Path -Parent $KitDir
134
+ $ProjectName = Split-Path -Leaf $ProjectRoot
135
+ $Today = Get-Date -Format 'yyyy-MM-dd'
136
+ $Timestamp = Get-Date -Format 'yyyyMMdd-HHmmss'
137
+
138
+ # ---- Init manifest state (lib\manifest.ps1) ----
139
+ $manifestState = Initialize-Manifest -ProjectRoot $ProjectRoot
140
+
141
+ # ---- Resolve label versi kit dari CHANGELOG.md (lib\version-detect.ps1) ----
142
+ $kitChangelog = Join-Path $KitDir 'CHANGELOG.md'
143
+ $detectedVersion = Get-KitVersionFromChangelog -ChangelogPath $kitChangelog
144
+ $KitVersion = if ($detectedVersion) { $detectedVersion } else { 'pre-launch (testing)' }
145
+
146
+ # ---- Validasi: root proyek terlihat valid ----
147
+ if (-not (Test-Path $ProjectRoot)) {
148
+ Write-Host "ERROR: Root proyek tidak ditemukan: $ProjectRoot" -ForegroundColor Red
149
+ Write-Host " Pastikan folder kit ini ada di dalam folder proyek." -ForegroundColor Red
150
+ exit 1
151
+ }
152
+
153
+ # ---- Strip .claude-kit/.git/ (lib\git-helpers.ps1) ----
154
+ # Saat kit di-clone (bukan zip-extract), folder .git/ ikut ke project. Bersihkan
155
+ # SEKALI di awal setup. Idempotent: skip kalau folder tidak ada.
156
+ if (-not $DryRun) {
157
+ $gitOk = Remove-GitMetadata -Path $KitDir
158
+ if ($gitOk) {
159
+ # Only print success kalau folder memang sempat ada (Remove-GitMetadata
160
+ # return $true juga untuk no-op). Cek silent: kalau .git masih ada = gagal.
161
+ if (-not (Test-Path -LiteralPath (Join-Path $KitDir '.git'))) {
162
+ # Silent kalau no-op (cleaner output); kit-clone case akan log via Write-Verbose.
163
+ }
164
+ } else {
165
+ Write-Host "WARN Gagal hapus .claude-kit\.git\ (lihat Write-Warning di atas)" -ForegroundColor Yellow
166
+ }
167
+ }
168
+
169
+ # ---- Mark-of-the-Web unblock (lib\git-helpers.ps1) ----
170
+ if (-not $DryRun) {
171
+ $motwOk = Remove-MotwBlock -Path $KitDir
172
+ if ($motwOk) {
173
+ Write-Host "OK Mark-of-the-Web di-unblock untuk semua file kit." -ForegroundColor Green
174
+ } else {
175
+ Write-Host "PERINGATAN: Unblock-File gagal (script tetap lanjut, mungkin perlu Unblock-File manual)" -ForegroundColor Yellow
176
+ }
177
+ }
178
+
179
+ # ---- Deteksi CLAUDE.md existing (proyek setengah jadi mungkin punya aturan custom) ----
180
+ $claudeMdPath = Join-Path $ProjectRoot 'CLAUDE.md'
181
+ if (Test-Path $claudeMdPath) {
182
+ Write-Host ""
183
+ Write-Host "DETEKSI: CLAUDE.md sudah ada di root proyek ($claudeMdPath)." -ForegroundColor Yellow
184
+ Write-Host " Pola B pakai AGENTS.md (BUKAN CLAUDE.md) untuk override proyek." -ForegroundColor Yellow
185
+ Write-Host " Kalau punya 2 file aturan, AI bisa bingung mana yang menang."
186
+ if (-not $Force -and -not $DryRun) {
187
+ Write-Host ""
188
+ Write-Host "Pilih aksi:" -ForegroundColor Cyan
189
+ Write-Host " [1] Rename CLAUDE.md jadi CLAUDE.md.legacy-$Timestamp lalu lanjut setup"
190
+ Write-Host " [2] Biarkan dua-duanya (AGENTS.md proyek menang per Path resolution rule)"
191
+ Write-Host " [3] Batalkan setup (mau merge manual dulu)"
192
+ $choice = '2'
193
+ try {
194
+ $choice = Read-Host "Pilih [1/2/3]"
195
+ if ([string]::IsNullOrWhiteSpace($choice)) { $choice = '2' }
196
+ } catch {
197
+ Write-Host "INFO: Shell NonInteractive terdeteksi, pakai default [2] biarkan CLAUDE.md." -ForegroundColor Yellow
198
+ Write-Host " (Jalankan di PowerShell window kalau mau pilih [1]/[3], atau pakai -Force untuk skip prompt.)" -ForegroundColor Yellow
199
+ $choice = '2'
200
+ }
201
+ switch ($choice) {
202
+ '1' {
203
+ $legacyName = "$claudeMdPath.legacy-$Timestamp"
204
+ try {
205
+ Move-Item $claudeMdPath $legacyName -Force
206
+ Write-Host "RENAMED $claudeMdPath -> $legacyName" -ForegroundColor Green
207
+ } catch {
208
+ Write-Host "GAGAL rename CLAUDE.md: $_" -ForegroundColor Red
209
+ Write-Host " Kemungkinan file lagi di-open di editor (VS Code/Notepad)." -ForegroundColor Red
210
+ Write-Host " Tutup editor + jalankan ulang script, atau pilih opsi [2] biarkan." -ForegroundColor Red
211
+ exit 1
212
+ }
213
+ }
214
+ '3' {
215
+ Write-Host "Dibatalkan. Setup tidak dilanjutkan." -ForegroundColor Yellow
216
+ exit 0
217
+ }
218
+ default {
219
+ Write-Host "INFO: Membiarkan CLAUDE.md existing. AGENTS.md baru akan dibuat." -ForegroundColor Cyan
220
+ Write-Host " Pastikan tim paham: AGENTS.md menang untuk override per Path resolution rule." -ForegroundColor Cyan
221
+ }
222
+ }
223
+ } elseif ($DryRun) {
224
+ Write-Host "[DRY] (interactive mode bakal tanya rename/biarkan/batal - pakai -Force untuk skip prompt)" -ForegroundColor Yellow
225
+ }
226
+ Write-Host ""
227
+ }
228
+
229
+ Write-Host ""
230
+ Write-Host "=== Setup Pola B (kit embed di proyek) ===" -ForegroundColor Cyan
231
+ Write-Host "Folder kit : $KitDir"
232
+ Write-Host "Root proyek : $ProjectRoot"
233
+ Write-Host "Nama proyek : $ProjectName"
234
+ Write-Host "Tanggal : $Today"
235
+ if ($DryRun) {
236
+ Write-Host "Mode : DRY-RUN (tidak ada file yang ditulis)" -ForegroundColor Yellow
237
+ }
238
+ Write-Host ""
239
+
240
+ # ---- Verifikasi file inti kit ada ----
241
+ # Source of truth: lib\kit-files.psd1 (single manifest, di-load semua konsumen)
242
+ $kitFilesPsd1 = Join-Path $KitDir 'lib\kit-files.psd1'
243
+ if (-not (Test-Path $kitFilesPsd1)) {
244
+ Write-Host "ERROR: lib\kit-files.psd1 hilang. Extract ulang zip kit." -ForegroundColor Red
245
+ exit 1
246
+ }
247
+ $kitFiles = Import-PowerShellDataFile -Path $kitFilesPsd1
248
+ $wajibAda = @(
249
+ $kitFiles.core_prompts +
250
+ $kitFiles.universal_rules +
251
+ $kitFiles.scripts +
252
+ $kitFiles.lib_files +
253
+ $kitFiles.templates +
254
+ $kitFiles.docs +
255
+ $kitFiles.tests +
256
+ $kitFiles.ci +
257
+ $kitFiles.meta
258
+ ) | ForEach-Object { $_ -replace '/', '\' }
259
+
260
+ $missing = @()
261
+ foreach ($f in $wajibAda) {
262
+ $p = Join-Path $KitDir $f
263
+ if (-not (Test-Path $p)) { $missing += $f }
264
+ }
265
+
266
+ if ($missing.Count -gt 0) {
267
+ Write-Host "ERROR: Kit tidak lengkap. File hilang:" -ForegroundColor Red
268
+ foreach ($f in $missing) { Write-Host " - $f" -ForegroundColor Red }
269
+ Write-Host ""
270
+ Write-Host " Extract ulang zip kit ke folder ini, lalu jalankan script lagi." -ForegroundColor Red
271
+ exit 1
272
+ }
273
+ Write-Host ("OK {0} file inti kit terverifikasi" -f $wajibAda.Count) -ForegroundColor Green
274
+
275
+ # ---- Deploy lib/ helper scripts (track ke manifest) ----
276
+ $libDir = Join-Path $KitDir 'lib'
277
+ if (-not (Test-Path $libDir)) {
278
+ if (-not $DryRun) {
279
+ New-Item -ItemType Directory -Path $libDir -Force | Out-Null
280
+ Add-DirToManifest -State $manifestState -DirPath $libDir
281
+ Write-Host "CREATED $libDir\" -ForegroundColor Green
282
+ } else {
283
+ Write-Host "[DRY] CREATE $libDir\" -ForegroundColor Yellow
284
+ }
285
+ }
286
+ $libFiles = @('rollback.ps1', 'safety.ps1', 'manifest-signing.ps1')
287
+ foreach ($lf in $libFiles) {
288
+ $lfPath = Join-Path $libDir $lf
289
+ if (Test-Path $lfPath) {
290
+ if (-not $DryRun) {
291
+ Add-ToManifest -State $manifestState -FilePath $lfPath -Kind 'lib' -From ('.claude-kit/lib/' + $lf)
292
+ Write-Host ("OK {0} (tracked)" -f $lfPath) -ForegroundColor Green
293
+ } else {
294
+ Write-Host ("[DRY] TRACK {0}" -f $lfPath) -ForegroundColor Yellow
295
+ }
296
+ } else {
297
+ Write-Host ("WARN lib file tidak ditemukan: {0} (skip track)" -f $lfPath) -ForegroundColor Yellow
298
+ }
299
+ }
300
+
301
+ # ---- Tanya optional info untuk fill placeholder ----
302
+ $ownerName = ''
303
+ $repoUrl = ''
304
+ if (-not $Force -and -not $DryRun) {
305
+ Write-Host ""
306
+ Write-Host "Optional: isi info berikut untuk pre-fill AGENTS.md (Enter = pakai default):" -ForegroundColor Cyan
307
+ try {
308
+ $ownerName = Read-Host ("Nama kamu (default: {0})" -f $env:USERNAME)
309
+ $repoUrl = Read-Host "URL repo standar tim (Enter = 'belum-ada')"
310
+ } catch {
311
+ Write-Host "INFO: Shell NonInteractive terdeteksi, pakai default value." -ForegroundColor Yellow
312
+ Write-Host " (Jalankan setup langsung di PowerShell window kalau mau isi prompt.)" -ForegroundColor Yellow
313
+ }
314
+ }
315
+ # Fallback default kalau kosong (skip prompt karena -Force/-DryRun, atau user tekan Enter)
316
+ if (-not $ownerName) { $ownerName = $env:USERNAME }
317
+ if (-not $repoUrl) { $repoUrl = 'belum-ada (solo project)' }
318
+
319
+ # ---- Setup AGENTS.md di root proyek (lib\agents-md.ps1) ----
320
+ $agentsTemplate = Join-Path $KitDir 'AGENTS.md.template'
321
+ $agentsTarget = Join-Path $ProjectRoot 'AGENTS.md'
322
+
323
+ # Decide preserve vs overwrite + handle interactive prompt
324
+ $shouldPreserve = $false
325
+ if (Test-Path $agentsTarget) {
326
+ if (-not $Force -and -not $DryRun) {
327
+ Write-Host ""
328
+ Write-Host "PERHATIAN: $agentsTarget sudah ada." -ForegroundColor Yellow
329
+ Write-Host " Pakai -Force untuk backup + timpa." -ForegroundColor Yellow
330
+ Write-Host " Atau hapus AGENTS.md existing manual, lalu jalankan script lagi." -ForegroundColor Yellow
331
+ $answer = 'N'
332
+ try {
333
+ $answer = Read-Host "Backup AGENTS.md existing + timpa dengan template baru? (Y/N)"
334
+ } catch {
335
+ Write-Host "INFO: Shell NonInteractive terdeteksi. AGENTS.md existing dipertahankan (default safe)." -ForegroundColor Yellow
336
+ Write-Host " Pakai -Force kalau memang mau timpa, atau jalankan di PowerShell window." -ForegroundColor Yellow
337
+ $answer = 'N'
338
+ }
339
+ if ($answer -notmatch '^[Yy]') {
340
+ Write-Host "Dibatalkan oleh user. AGENTS.md existing tidak diubah." -ForegroundColor Yellow
341
+ Write-Host "Setup tetap OK - kit di .claude-kit\ siap dipakai." -ForegroundColor Green
342
+ exit 0
343
+ }
344
+ }
345
+ }
346
+
347
+ # Build placeholder set (shared dengan docs/ templates di bawah)
348
+ $agentsPlaceholders = @{
349
+ '<NAMA_PROYEK>' = $ProjectName
350
+ '<TANGGAL_HARI_INI>' = $Today
351
+ '<NAMA_KAMU>' = $ownerName
352
+ '<URL_REPO_STANDAR>' = $repoUrl
353
+ '<VERSI_KIT>' = $KitVersion
354
+ }
355
+
356
+ if ($DryRun) {
357
+ Write-Host "[DRY] DEPLOY AGENTS.md (template fill + backup kalau existing)" -ForegroundColor Yellow
358
+ Write-Host "[DRY] Placeholders: NAMA_PROYEK='$ProjectName', TANGGAL_HARI_INI='$Today', VERSI_KIT='$KitVersion'" -ForegroundColor Yellow
359
+ } else {
360
+ try {
361
+ $deployResult = Deploy-AgentsMd `
362
+ -ProjectRoot $ProjectRoot `
363
+ -TemplatePath $agentsTemplate `
364
+ -Placeholders $agentsPlaceholders
365
+ # Track backup ke manifest kalau ada
366
+ if ($deployResult.backup_path) {
367
+ Add-ToManifest -State $manifestState -FilePath $deployResult.backup_path -Kind 'backup' -From 'AGENTS.md (pre-Force backup)'
368
+ Write-Host "BACKUP $agentsTarget -> $($deployResult.backup_path)" -ForegroundColor Yellow
369
+ }
370
+ Add-ToManifest -State $manifestState -FilePath $deployResult.target_path -Kind 'filled_template' -From 'AGENTS.md.template'
371
+ Write-Host "OK $($deployResult.target_path)" -ForegroundColor Green
372
+ $filled = "NAMA_PROYEK='$ProjectName', TANGGAL_HARI_INI='$Today', NAMA_KAMU='$ownerName', URL_REPO_STANDAR='$repoUrl', VERSI_KIT='$KitVersion'"
373
+ Write-Host " Pre-filled: $filled" -ForegroundColor Green
374
+ } catch {
375
+ Write-Host "GAGAL deploy AGENTS.md: $_" -ForegroundColor Red
376
+ exit 1
377
+ }
378
+ }
379
+
380
+ # ---- Bootstrap docs/ skeleton ----
381
+ $docsDir = Join-Path $ProjectRoot 'docs'
382
+
383
+ # Sanity check: proyek hampir kosong? Skip docs/ skeleton supaya tidak prematur.
384
+ $excludeNames = @(
385
+ '.git', '.claude-kit', 'AGENTS.md', 'docs',
386
+ 'node_modules', 'vendor', 'dist', 'build', 'out', 'target',
387
+ '__pycache__', '.venv', 'venv', '.next', '.nuxt', '.turbo', '.cache'
388
+ )
389
+ $nonHiddenFiles = @(Get-ChildItem -Path $ProjectRoot -Force -ErrorAction SilentlyContinue | Where-Object {
390
+ $_.Name -notin $excludeNames -and -not $_.Name.StartsWith('.')
391
+ })
392
+ $proyekHampirKosong = ($nonHiddenFiles.Count -le 1)
393
+
394
+ if ($proyekHampirKosong) {
395
+ Write-Host ""
396
+ Write-Host "INFO: Proyek terlihat hampir kosong - skip docs/ skeleton (terlalu prematur)." -ForegroundColor Cyan
397
+ Write-Host " Setelah ada code, jalankan ulang AI dengan prompt PROJECT_LIFECYCLE_PROMPT_v1.md (Stage B: Bootstrap Docs)" -ForegroundColor Cyan
398
+ } else {
399
+ if (-not (Test-Path $docsDir)) {
400
+ if (-not $DryRun) {
401
+ New-Item -ItemType Directory -Path $docsDir -Force | Out-Null
402
+ Add-DirToManifest -State $manifestState -DirPath $docsDir
403
+ Write-Host ""
404
+ Write-Host "CREATED $docsDir\" -ForegroundColor Green
405
+ } else {
406
+ Write-Host "[DRY] CREATE $docsDir\" -ForegroundColor Yellow
407
+ }
408
+ }
409
+
410
+ # Templates dengan placeholder substitution
411
+ $docsTemplatesWithPlaceholder = @(
412
+ @{ Src = 'templates\architecture.md'; Dst = (Join-Path $docsDir 'architecture.md'); From = 'templates/architecture.md'; Placeholders = @{
413
+ '<NAMA_PROYEK>' = $ProjectName
414
+ '[TBD: tanggal hari ini, format YYYY-MM-DD]' = $Today
415
+ '[TBD: YYYY-MM-DD]' = $Today
416
+ }},
417
+ @{ Src = 'templates\glossary.md'; Dst = (Join-Path $docsDir 'glossary.md'); From = 'templates/glossary.md'; Placeholders = @{
418
+ '<NAMA_PROYEK>' = $ProjectName
419
+ '<YYYY-MM-DD>' = $Today
420
+ }}
421
+ )
422
+ foreach ($t in $docsTemplatesWithPlaceholder) {
423
+ $tSrc = Join-Path $KitDir $t.Src
424
+ $tDst = $t.Dst
425
+ if (Test-Path $tDst) {
426
+ Write-Host "SKIP $tDst (sudah ada, tidak di-overwrite)" -ForegroundColor Yellow
427
+ } elseif (-not (Test-Path $tSrc)) {
428
+ Write-Host ("WARN Template tidak ditemukan: {0} (skip)" -f $tSrc) -ForegroundColor Yellow
429
+ } elseif (-not $DryRun) {
430
+ $r = Copy-TemplateWithPlaceholder -SourcePath $tSrc -TargetPath $tDst -Placeholders $t.Placeholders -IfExists 'Skip'
431
+ if ($r.copied) {
432
+ Add-ToManifest -State $manifestState -FilePath $tDst -Kind 'skeleton' -From $t.From
433
+ Write-Host ("OK {0} (skeleton, pre-filled NAMA_PROYEK='{1}')" -f $tDst, $ProjectName) -ForegroundColor Green
434
+ } elseif ($r.action -eq 'missing') {
435
+ Write-Host ("GAGAL copy {0}: source missing" -f $t.Dst) -ForegroundColor Red
436
+ }
437
+ } else {
438
+ Write-Host "[DRY] COPY $tSrc -> $tDst" -ForegroundColor Yellow
439
+ }
440
+ }
441
+
442
+ # 3 file template tambahan (tanpa placeholder substitution, plain copy)
443
+ $extraTemplates = @(
444
+ @{ TemplateName = '_PATTERNS.md'; TargetName = '_PATTERNS.md'; Desc = 'aturan dokumentasi tim profesional generic' },
445
+ @{ TemplateName = '_EXAMPLE.md'; TargetName = '_EXAMPLE.md'; Desc = 'contoh format .md pendamping siap-copy' },
446
+ @{ TemplateName = 'architecture_auto.md'; TargetName = 'architecture_auto.md'; Desc = 'registry TOC AI-maintained skeleton' }
447
+ )
448
+ foreach ($t in $extraTemplates) {
449
+ $tSrc = Join-Path $KitDir ('templates\' + $t.TemplateName)
450
+ $tDst = Join-Path $docsDir $t.TargetName
451
+ if (Test-Path $tDst) {
452
+ Write-Host "SKIP $tDst (sudah ada, tidak di-overwrite)" -ForegroundColor Yellow
453
+ } elseif (-not (Test-Path $tSrc)) {
454
+ Write-Host ("WARN Template tidak ditemukan: {0} (skip)" -f $tSrc) -ForegroundColor Yellow
455
+ } elseif (-not $DryRun) {
456
+ $r = Copy-StaticTemplate -SourcePath $tSrc -TargetPath $tDst -IfExists 'Skip'
457
+ if ($r.copied) {
458
+ Add-ToManifest -State $manifestState -FilePath $tDst -Kind 'skeleton' -From ('templates/' + $t.TemplateName)
459
+ Write-Host ("OK {0} ({1})" -f $tDst, $t.Desc) -ForegroundColor Green
460
+ } elseif ($r.action -eq 'missing') {
461
+ Write-Host ("GAGAL copy {0}: source missing" -f $t.TargetName) -ForegroundColor Red
462
+ }
463
+ } else {
464
+ Write-Host "[DRY] COPY $tSrc -> $tDst" -ForegroundColor Yellow
465
+ }
466
+ }
467
+ }
468
+
469
+ # ---- Bootstrap TIM files (Team Mode T = default) ----
470
+ if (-not $SkipTeamFiles -and -not $proyekHampirKosong) {
471
+ Write-Host ""
472
+ Write-Host "=== Copy file tim (Team Mode) ===" -ForegroundColor Cyan
473
+
474
+ # Buat folder .github/ + workflows + scripts kalau belum ada
475
+ $githubDir = Join-Path $ProjectRoot '.github'
476
+ $workflowsDir = Join-Path $githubDir 'workflows'
477
+ $scriptsDir = Join-Path $githubDir 'scripts'
478
+ foreach ($d in @($githubDir, $workflowsDir, $scriptsDir)) {
479
+ if (-not (Test-Path $d) -and -not $DryRun) {
480
+ New-Item -ItemType Directory -Path $d -Force | Out-Null
481
+ Add-DirToManifest -State $manifestState -DirPath $d
482
+ Write-Host ("CREATED {0}\" -f $d) -ForegroundColor Green
483
+ }
484
+ }
485
+
486
+ # Buat folder docs/decisions/ kalau belum ada
487
+ $decisionsDir = Join-Path $docsDir 'decisions'
488
+ if (-not (Test-Path $decisionsDir) -and -not $DryRun) {
489
+ New-Item -ItemType Directory -Path $decisionsDir -Force | Out-Null
490
+ Add-DirToManifest -State $manifestState -DirPath $decisionsDir
491
+ Write-Host ("CREATED {0}\" -f $decisionsDir) -ForegroundColor Green
492
+ }
493
+
494
+ # Mapping file tim: src (di .claude-kit) -> dst (di project root)
495
+ $teamFiles = @(
496
+ @{ Src = 'templates\github\workflows\ai-review.yml'; Dst = (Join-Path $workflowsDir 'ai-review.yml'); Desc = 'GitHub Action Senior AI Reviewer' },
497
+ @{ Src = 'templates\github\workflows\backup-schemas.yml'; Dst = (Join-Path $workflowsDir 'backup-schemas.yml'); Desc = 'GitHub Action daily backup pg_dump per-schema (L3 backup)' },
498
+ @{ Src = 'templates\github\scripts\ai-review.js'; Dst = (Join-Path $scriptsDir 'ai-review.js'); Desc = 'Script Senior AI Reviewer' },
499
+ @{ Src = 'templates\github\CODEOWNERS.template'; Dst = (Join-Path $githubDir 'CODEOWNERS'); Desc = 'CODEOWNERS template (WAJIB edit dengan username actual)' },
500
+ @{ Src = 'templates\github\pull_request_template.md'; Dst = (Join-Path $githubDir 'pull_request_template.md'); Desc = 'PR template tim' },
501
+ @{ Src = 'templates\CLAUDE_TEAM_GUIDE.md'; Dst = (Join-Path $docsDir 'CLAUDE_TEAM_GUIDE.md'); Desc = 'Panduan tim AI-first' },
502
+ @{ Src = 'templates\PROMPT_LIBRARY.md'; Dst = (Join-Path $docsDir 'PROMPT_LIBRARY.md'); Desc = '15 prompt pattern siap-pakai (1-10 generic + 11-15 chat-driven)' },
503
+ @{ Src = 'templates\ONBOARDING.md'; Dst = (Join-Path $docsDir 'ONBOARDING.md'); Desc = 'Playbook dev baru' },
504
+ @{ Src = 'templates\STACK_GUIDE.md'; Dst = (Join-Path $docsDir 'STACK_GUIDE.md'); Desc = 'Next.js + Vercel + SEO + security' },
505
+ @{ Src = 'templates\STACK_MIGRATION_GUIDE.md'; Dst = (Join-Path $docsDir 'STACK_MIGRATION_GUIDE.md'); Desc = 'Migrasi Vercel -> Railway/Render (ADVANCED post-launch)' },
506
+ @{ Src = 'templates\MCP_SETUP.md'; Dst = (Join-Path $docsDir 'MCP_SETUP.md'); Desc = 'MCP setup + Decision Tree Postgres/Supabase' },
507
+ @{ Src = 'templates\RLS_SETUP_PROMPT.md'; Dst = (Join-Path $docsDir 'RLS_SETUP_PROMPT.md'); Desc = 'RLS setup prompt untuk staff IT schema-scoped' },
508
+ @{ Src = 'templates\DB_SCHEMA_SCAN_PROMPT.md'; Dst = (Join-Path $docsDir 'DB_SCHEMA_SCAN_PROMPT.md'); Desc = 'Scan DB schema -> docs/db-schema.md' },
509
+ @{ Src = 'templates\GLOSSARY_NON_PROGRAMMER.md'; Dst = (Join-Path $docsDir 'GLOSSARY_NON_PROGRAMMER.md'); Desc = 'Glossary istilah teknis untuk non-programmer (WAJIB baca dulu)' },
510
+ @{ Src = 'templates\ANALOGI_LIBRARY.md'; Dst = (Join-Path $docsDir 'ANALOGI_LIBRARY.md'); Desc = '30 jargon teknis x 3-layer analogi tools digital populer Indonesia (cadangan rujukan AI)' },
511
+ @{ Src = 'templates\UPDATE_GUIDE.md'; Dst = (Join-Path $docsDir 'UPDATE_GUIDE.md'); Desc = 'Panduan staff IT non-programmer cara update kit (4-tier strategy + analogi tools digital)' },
512
+ @{ Src = 'templates\SECURITY_INCIDENT_PLAYBOOK.md'; Dst = (Join-Path $docsDir 'SECURITY_INCIDENT_PLAYBOOK.md'); Desc = 'Security incident playbook (kalau token bocor / data leak)' },
513
+ @{ Src = 'templates\feature-flags-advanced.md'; Dst = (Join-Path $docsDir 'feature-flags-advanced.md'); Desc = 'Feature flag pattern (ADVANCED, post-launch only)' },
514
+ @{ Src = 'templates\decisions\_TEMPLATE.md'; Dst = (Join-Path $decisionsDir '_TEMPLATE.md'); Desc = 'ADR template' },
515
+ @{ Src = 'templates\decisions\README.md'; Dst = (Join-Path $decisionsDir 'README.md'); Desc = 'ADR folder README' }
516
+ )
517
+
518
+ foreach ($t in $teamFiles) {
519
+ $tSrc = Join-Path $KitDir $t.Src
520
+ $tDst = $t.Dst
521
+ if (Test-Path $tDst) {
522
+ Write-Host ("SKIP {0} (sudah ada, tidak di-overwrite)" -f $tDst) -ForegroundColor Yellow
523
+ } elseif (-not (Test-Path $tSrc)) {
524
+ Write-Host ("WARN File tim tidak ditemukan di kit: {0} (skip)" -f $tSrc) -ForegroundColor Yellow
525
+ } elseif (-not $DryRun) {
526
+ $r = Copy-StaticTemplate -SourcePath $tSrc -TargetPath $tDst -IfExists 'Skip'
527
+ if ($r.copied) {
528
+ # Pakai forward slash di field 'from' supaya konsisten cross-platform di JSON
529
+ $fromRel = $t.Src.Replace('\','/')
530
+ Add-ToManifest -State $manifestState -FilePath $tDst -Kind 'team_file' -From $fromRel
531
+ Write-Host ("OK {0} ({1})" -f $tDst, $t.Desc) -ForegroundColor Green
532
+ } elseif ($r.action -eq 'missing') {
533
+ Write-Host ("GAGAL copy {0}: source missing" -f $t.Src) -ForegroundColor Red
534
+ }
535
+ } else {
536
+ Write-Host "[DRY] COPY $tSrc -> $tDst" -ForegroundColor Yellow
537
+ }
538
+ }
539
+
540
+ # Copy docs/SIGNED_RELEASE.md (sourced dari kit's docs/ folder, bukan templates/)
541
+ $signedReleaseSrc = Join-Path $KitDir 'docs\SIGNED_RELEASE.md'
542
+ $signedReleaseDst = Join-Path $docsDir 'SIGNED_RELEASE.md'
543
+ if (Test-Path $signedReleaseDst) {
544
+ Write-Host ("SKIP {0} (sudah ada, tidak di-overwrite)" -f $signedReleaseDst) -ForegroundColor Yellow
545
+ } elseif (-not (Test-Path $signedReleaseSrc)) {
546
+ Write-Host ("WARN docs/SIGNED_RELEASE.md tidak ditemukan di kit: {0} (skip)" -f $signedReleaseSrc) -ForegroundColor Yellow
547
+ } elseif (-not $DryRun) {
548
+ # Pastikan docs/ ada (edge case kalau heuristic skip creation tapi user disable -SkipTeamFiles)
549
+ if (-not (Test-Path $docsDir)) {
550
+ New-Item -ItemType Directory -Path $docsDir -Force | Out-Null
551
+ Add-DirToManifest -State $manifestState -DirPath $docsDir
552
+ }
553
+ $r = Copy-StaticTemplate -SourcePath $signedReleaseSrc -TargetPath $signedReleaseDst -IfExists 'Skip'
554
+ if ($r.copied) {
555
+ Add-ToManifest -State $manifestState -FilePath $signedReleaseDst -Kind 'team_file' -From 'docs/SIGNED_RELEASE.md'
556
+ Write-Host ("OK {0} (panduan verifikasi signed release)" -f $signedReleaseDst) -ForegroundColor Green
557
+ }
558
+ } else {
559
+ Write-Host "[DRY] COPY $signedReleaseSrc -> $signedReleaseDst" -ForegroundColor Yellow
560
+ }
561
+
562
+ Write-Host ""
563
+ Write-Host "REMINDER untuk Team Mode:" -ForegroundColor Cyan
564
+ Write-Host " 1. Edit .github\CODEOWNERS - ganti placeholder dengan GitHub username actual."
565
+ Write-Host " 2. Setup ANTHROPIC_API_KEY di GitHub repo Settings -> Secrets -> Actions."
566
+ Write-Host " 3. Baca docs\CLAUDE_TEAM_GUIDE.md (panduan tim) + docs\PROMPT_LIBRARY.md."
567
+ Write-Host " 4. Kalau pakai DB: setup schema isolation + RLS:"
568
+ Write-Host " - docs\MCP_SETUP.md (PostgreSQL MCP default, Supabase MCP owner-only)"
569
+ Write-Host " - docs\RLS_SETUP_PROMPT.md (paste prompt RLS untuk staff IT)"
570
+ Write-Host " - docs\DB_SCHEMA_SCAN_PROMPT.md (paste prompt scan schema -> docs\db-schema.md)"
571
+ } elseif ($SkipTeamFiles) {
572
+ Write-Host ""
573
+ Write-Host "INFO: -SkipTeamFiles aktif (advanced escape hatch) - skip copy .github/ + docs tim." -ForegroundColor Cyan
574
+ }
575
+
576
+ # ---- Save install manifest (lib\manifest.ps1 — merge + HMAC sign + write JSON) ----
577
+ if (-not $DryRun) {
578
+ try {
579
+ $saveResult = Save-Manifest `
580
+ -State $manifestState `
581
+ -KitDir $KitDir `
582
+ -KitVersion $KitVersion `
583
+ -ProjectName $ProjectName
584
+
585
+ # ---- Ensure .claude-kit/.gitignore ignore manifest + backup files ----
586
+ # APPEND-if-missing pattern: preserve existing .gitignore, tambah entries yang belum ada.
587
+ $gitignorePath = Join-Path $KitDir '.gitignore'
588
+ $requiredEntries = @(
589
+ '.install-manifest.json',
590
+ '*.bak',
591
+ '*.backup-*',
592
+ '*.env',
593
+ '*.env.local',
594
+ '*.pem',
595
+ '*.key'
596
+ )
597
+ $existingLines = @()
598
+ if (Test-Path -LiteralPath $gitignorePath) {
599
+ $existingLines = @(Get-Content -LiteralPath $gitignorePath -Encoding UTF8 -ErrorAction SilentlyContinue)
600
+ }
601
+ $missingEntries = @($requiredEntries | Where-Object { $existingLines -notcontains $_ })
602
+ if ($missingEntries.Count -gt 0) {
603
+ $appendBlock = "`n# Auto-appended oleh setup-pola-b.ps1 (lintasAI safe-uninstall hardening):`n# Cegah leak environment metadata + secret kalau user run ``git add .claude-kit/``.`n"
604
+ $appendBlock += ($missingEntries -join "`n") + "`n"
605
+ if ($existingLines.Count -gt 0) {
606
+ [System.IO.File]::AppendAllText($gitignorePath, $appendBlock, (New-Object System.Text.UTF8Encoding $false))
607
+ } else {
608
+ [System.IO.File]::WriteAllText($gitignorePath, $appendBlock.TrimStart("`n"), (New-Object System.Text.UTF8Encoding $false))
609
+ }
610
+ }
611
+
612
+ Write-Host ""
613
+ Write-Host ("OK .install-manifest.json written ({0} file + {1} dir tracked)" -f $saveResult.FilesCount, $saveResult.DirsCount) -ForegroundColor Green
614
+ if ($saveResult.Merged) {
615
+ Write-Host " Merged dengan manifest sebelumnya (re-run setup detected)." -ForegroundColor DarkGray
616
+ }
617
+ if ($saveResult.Signed) {
618
+ Write-Host " HMAC-signed (tamper-detection aktif)." -ForegroundColor DarkGray
619
+ }
620
+ Write-Host " Dipakai uninstall.ps1 untuk safe delete (hash-based pristine detection)." -ForegroundColor DarkGray
621
+ Write-Host " Anonymized: project_root='<PROJECT_ROOT>', installed_by='<USER>' (tidak leak env)." -ForegroundColor DarkGray
622
+ } catch {
623
+ Write-Host "WARN Gagal tulis .install-manifest.json: $_" -ForegroundColor Yellow
624
+ Write-Host " Setup TETAP berhasil, tapi uninstall.ps1 nanti minta fallback manual." -ForegroundColor Yellow
625
+ }
626
+ }
627
+
628
+ # ---- Ringkasan akhir (structured + actionable) ----
629
+ Write-Host ""
630
+ Write-Host "================================================================" -ForegroundColor Green
631
+ Write-Host (" OK KIT lintasAI - TER-INSTALL DI {0}" -f $ProjectName) -ForegroundColor Green
632
+ Write-Host "================================================================" -ForegroundColor Green
633
+ Write-Host ""
634
+
635
+ Write-Host "SUDAH AKTIF (auto-load tiap sesi AI):" -ForegroundColor Cyan
636
+ Write-Host " [x] Aturan AI : 4 rule docs + Tinjauan Multi-Divisi (12 divisi)"
637
+ if ($proyekHampirKosong) {
638
+ Write-Host " [ ] docs/ : SKIP (proyek hampir kosong) - akan auto-generate saat ada code"
639
+ Write-Host " [ ] .github/ : SKIP (proyek hampir kosong) - team files belum di-copy"
640
+ } else {
641
+ Write-Host " [x] docs/ : skeleton + panduan tim (architecture, glossary, _PATTERNS, dst.)"
642
+ if (-not $SkipTeamFiles) {
643
+ Write-Host " [x] .github/ : ai-review.yml + CODEOWNERS + PR template"
644
+ } else {
645
+ Write-Host " [ ] .github/ : SKIP (-SkipTeamFiles aktif)"
646
+ }
647
+ }
648
+ Write-Host " [x] Path resolution : ~/.claude/ -> .claude-kit/"
649
+ Write-Host ""
650
+
651
+ Write-Host "ACTION ITEMS - PERLU KAMU LAKUKAN MANUAL:" -ForegroundColor Yellow
652
+ $itemIdx = 1
653
+ if (-not $SkipTeamFiles -and -not $proyekHampirKosong) {
654
+ Write-Host (" [ ] ({0}) ~5 menit Edit .github/CODEOWNERS - ganti placeholder @username dengan GitHub username actual." -f $itemIdx)
655
+ $itemIdx++
656
+ Write-Host (" [ ] ({0}) ~2 menit Setup ANTHROPIC_API_KEY di GitHub: Settings -> Secrets and variables -> Actions -> New secret." -f $itemIdx)
657
+ $itemIdx++
658
+ }
659
+ Write-Host (" [ ] ({0}) opsional Baca docs/CLAUDE_TEAM_GUIDE.md (panduan tim) + docs/PROMPT_LIBRARY.md." -f $itemIdx)
660
+ $itemIdx++
661
+ Write-Host (" [ ] ({0}) opsional Commit setup ke git: git add AGENTS.md .claude-kit/ docs/ .github/ && git commit -m 'chore: setup standar tim IT'" -f $itemIdx)
662
+ Write-Host ""
663
+
664
+ Write-Host "LANGKAH SELANJUTNYA - 1 PERINTAH:" -ForegroundColor Cyan
665
+ Write-Host (" Buka Claude Code di {0}, paste isi:" -f $ProjectRoot)
666
+ Write-Host (" {0}\JALANKAN_KIT.md" -f $KitDir) -ForegroundColor Green
667
+ Write-Host ""
668
+ Write-Host " AI akan otomatis pandu kamu lewat 3 interactive popup:" -ForegroundColor Cyan
669
+ Write-Host " 1. Team Mode? (T) scan + bulk-bootstrap / (skip) langsung kerja"
670
+ Write-Host " 2. Bulk-bootstrap? (1) all / (2) per kategori / (3) skeleton-first -- kalau pilih T"
671
+ Write-Host " 3. Skenario? (a) proyek baru / (c) proyek setengah jadi / (d) langsung ngoding"
672
+ Write-Host ""
673
+ Write-Host " Default tiap popup (kosong/Enter): T -> 1 -> d (owner-grade full docs)" -ForegroundColor Green
674
+ Write-Host ""
675
+ Write-Host " Alternatif (skip JALANKAN_KIT): langsung ngoding aja - aturan AI tetap auto-load tiap"
676
+ Write-Host " sesi, LAZY-GENERATE aktif saat sentuh code CRITICAL."
677
+ Write-Host ""
678
+ Write-Host "UPDATE KIT KE VERSI BARU:" -ForegroundColor Cyan
679
+ Write-Host " .\.claude-kit\update-kit.ps1 (auto re-clone + backup + detect [BREAKING]/[SCAN-REQUIRED])"
680
+ Write-Host ""
681
+
682
+ if ($DryRun) {
683
+ Write-Host "Mode DRY-RUN: jalankan ulang tanpa -DryRun untuk eksekusi sungguhan." -ForegroundColor Yellow
684
+ }
685
+ Write-Host "Status: SIAP NGODING" -ForegroundColor Green
686
+ Write-Host ""
687
+ exit 0