@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,213 @@
1
+ # UPDATE_KIT_PROMPT_v1.md — Prompt Update Kit lintasAI (Single-Paste)
2
+
3
+ > Versi: v1 · Untuk staff IT non-programmer · Bahasa Indonesia
4
+ > Pasangan dari `JALANKAN_KIT.md` (setup awal). File ini = **update kit** yang sudah terpasang.
5
+
6
+ ---
7
+
8
+ ## Cara pakai
9
+
10
+ Paste **seluruh isi file ini** ke Claude Code (di project yang sudah pakai lintasAI). AI akan otomatis cek versi, jelaskan apa yang berubah pakai analogi yang gampang, minta konfirmasi sekali, lalu eksekusi update-nya.
11
+
12
+ Anggap aja seperti **update aplikasi WhatsApp di HP**: kamu tinggal tekan "Update", aplikasi yang ngurus sendiri — kamu cuma kasih izin sekali di awal.
13
+
14
+ ---
15
+
16
+ ## Implicit consent
17
+
18
+ Dengan paste prompt ini, kamu (staff) **memberi izin AI untuk**:
19
+
20
+ 1. Baca `AGENTS.md` + `./.claude-kit/CHANGELOG.md` (cek versi kit yang lagi terpasang).
21
+ 2. Tarik info versi terbaru dari GitHub remote (`github.com/ojokesusu/lintasAI`).
22
+ 3. Jalankan `./.claude-kit/kit.ps1 update` kalau memang ada versi baru.
23
+ 4. Backup kit lama otomatis (`.bak` files) sebelum re-clone.
24
+ 5. Cleanup backup lama (> 30 hari atau lebih dari 3 versi terakhir).
25
+
26
+ AI **tidak akan** sentuh file project kamu (kode app, `docs/`, `AGENTS.md` kamu) — itu dilindungi manifest sha256 (sama persis logic-nya kayak `uninstall.ps1`).
27
+
28
+ ---
29
+
30
+ ## Workflow yang AI jalankan
31
+
32
+ Ikuti urutan ini step-by-step. Jangan skip step kecuali user bilang skip eksplisit.
33
+
34
+ ### Step 1 — Baca versi kit yang terpasang
35
+
36
+ Buka file:
37
+ - `./AGENTS.md` → cari field "Versi kit di `./.claude-kit/`" (contoh: `v1.0.0`).
38
+ - `./.claude-kit/CHANGELOG.md` → konfirmasi versi terbaru di file lokal (entry paling atas).
39
+
40
+ Catat: `CURRENT_VERSION = v1.x.y`.
41
+
42
+ ### Step 2 — Cek versi terbaru di GitHub
43
+
44
+ Jalankan (silent, tanpa output panjang):
45
+ ```powershell
46
+ git ls-remote --tags https://github.com/ojokesusu/lintasAI | Select-String -Pattern "refs/tags/v" | ForEach-Object { ($_ -split "refs/tags/")[1] } | Sort-Object -Descending | Select-Object -First 1
47
+ ```
48
+
49
+ Atau alternatif: fetch `CHANGELOG.md` di branch `main` GitHub via WebFetch (kalau git remote belum di-config).
50
+
51
+ Catat: `LATEST_VERSION = v1.x.z`.
52
+
53
+ ### Step 3 — Bandingkan
54
+
55
+ Kalau `CURRENT_VERSION == LATEST_VERSION`:
56
+ > "Kit lintasAI kamu udah versi terbaru (`v1.x.y`). Kayak buka Tokopedia trus dia bilang 'Sudah versi terbaru' — gak perlu update. Selesai."
57
+
58
+ Stop di sini. **Jangan** lanjut step 4+.
59
+
60
+ Kalau beda → lanjut step 4.
61
+
62
+ ### Step 4 — Parse CHANGELOG entries di antara versi
63
+
64
+ Baca `./.claude-kit/CHANGELOG.md` (lokal = versi lama) **dan** CHANGELOG terbaru dari GitHub remote. Ambil semua entry antara `CURRENT_VERSION` (exclusive) sampai `LATEST_VERSION` (inclusive).
65
+
66
+ Contoh: current `v1.0.0`, latest `v1.2.0` → parse entry `v1.0.1`, `v1.0.2`, `v1.1.0`, `v1.2.0`.
67
+
68
+ ### Step 5 — Auto-classify per entry ke Tier 1-4
69
+
70
+ Logic klasifikasi:
71
+
72
+ | Tier | Trigger label/content | Analogi tools digital |
73
+ |------|----------------------|-----------------------|
74
+ | **Tier 1 (Silent)** | Patch version bump tanpa label apapun. Isi: typo, fix grammar, link mati. | WhatsApp `2.23.10 → 2.23.11` auto-update di background — kamu gak ngerasa apa-apa, tau-tau udah update. |
75
+ | **Tier 2 (AI auto-sync)** | Minor version bump tanpa label. Isi: aturan baru, template baru, section CLAUDE_universal baru. | iPhone `iOS 17.3 → 17.4` minor — fitur baru aktif setelah restart, tapi cara pakai HP-mu gak berubah. |
76
+ | **Tier 3 ([BREAKING])** | Label `[BREAKING]` di CHANGELOG. Isi: struktur file pindah, format manifest ganti, naming convention diubah. | iPhone `iOS 16 → iOS 17` major — backup wajib, ada migration screen pas booting pertama. |
77
+ | **Tier 4 ([SCAN-REQUIRED])** | Label `[SCAN-REQUIRED]`. Isi: bulk-bootstrap logic ganti, scan rule baru yang harus apply ke project lama. | Tokopedia Seller ganti algoritma kategori — produk lama harus di-remap ulang ke kategori baru, bukan cuma update app. |
78
+
79
+ Default kalau ragu antara Tier 1 vs Tier 2: pilih **Tier 2** (lebih informatif buat user).
80
+ Default kalau ragu antara Tier 3 vs Tier 4: cek apakah ada instruksi "scan project ulang" di CHANGELOG. Ya → Tier 4, tidak → Tier 3.
81
+
82
+ ### Step 6 — Compose summary (Bahasa Indonesia + analogi wajib)
83
+
84
+ Format laporan ke staff:
85
+
86
+ ```
87
+ Update tersedia: v1.0.0 → v1.2.0
88
+
89
+ Yang berubah:
90
+ [Tier 1: 3 perbaikan kecil]
91
+ Kayak WhatsApp auto-update — ada perbaikan typo & link mati,
92
+ tapi cara kamu pakai kit gak berubah sama sekali.
93
+
94
+ [Tier 2: 1 aturan baru]
95
+ Section 4.5 di CLAUDE_universal_v1.md ("Audit Post-Setup Pattern").
96
+ Kayak iPhone dapat fitur baru di iOS minor update — AI otomatis
97
+ mulai pakai aturan ini abis update. Kamu gak perlu hafal.
98
+
99
+ [Tier 3: kosong]
100
+ [Tier 4: kosong]
101
+
102
+ Yang ke-update: 4 file di ./.claude-kit/
103
+ Yang ke-backup otomatis: ./.claude-kit.bak-2026-06-04/
104
+ Yang DILINDUNGI (gak disentuh):
105
+ - File project kamu (kode app, docs/, dll)
106
+ - AGENTS.md kamu (custom override per project)
107
+
108
+ Action yang perlu kamu lakuin abis update:
109
+ TIDAK ADA — langsung lanjut kerja seperti biasa.
110
+ AI akan otomatis pakai aturan baru di sesi berikutnya.
111
+ ```
112
+
113
+ Kalau ada Tier 3 → tambah section:
114
+ ```
115
+ PERHATIAN [BREAKING]:
116
+ [judul perubahan]
117
+ Migration Steps (inline dari CHANGELOG):
118
+ 1. <command PS>
119
+ 2. <command PS>
120
+ Estimasi waktu: <X menit>
121
+ ```
122
+
123
+ Kalau ada Tier 4 → tambah section:
124
+ ```
125
+ PERHATIAN [SCAN-REQUIRED]:
126
+ Abis update, paste JALANKAN_KIT.md ulang biar AI scan project
127
+ pakai aturan baru. Kayak Tokopedia minta re-mapping produk lama
128
+ ke kategori baru.
129
+ ```
130
+
131
+ ### Step 7 — Popup konfirmasi (default Y)
132
+
133
+ Tanya staff:
134
+ > "Lanjut update sekarang? (Y/n, default Y)"
135
+
136
+ Karena user mode `Edit automatically` + bypass Y/N (lihat feedback_auto_confirm), kalau staff gak nge-reply spesifik "n" → **assume YES**, lanjut step 8.
137
+
138
+ Kalau "n" → "Oke, update di-cancel. Kit masih di `v1.x.y`. Paste prompt ini lagi kalau berubah pikiran." → stop.
139
+
140
+ ### Step 8 — Execute update
141
+
142
+ Jalankan:
143
+ ```powershell
144
+ ./.claude-kit/kit.ps1 update
145
+ ```
146
+
147
+ Script ini yang akan:
148
+ 1. Atomic re-clone dari GitHub tag `LATEST_VERSION`.
149
+ 2. Backup folder lama ke `.claude-kit.bak-<tanggal>`.
150
+ 3. Cek manifest sha256 → file yang user modify (selain template) di-preserve.
151
+ 4. Cleanup `.bak` files > 30 hari atau lebih dari 3 versi terakhir.
152
+ 5. Update field versi di `AGENTS.md`.
153
+
154
+ Kalau script fail di tengah jalan → auto-rollback (kit balik ke `CURRENT_VERSION`). Lapor error ke staff.
155
+
156
+ ### Step 9 — Laporan hasil + recommend next step
157
+
158
+ Format laporan sukses:
159
+ ```
160
+ Update beres. Kit sekarang v1.2.0.
161
+
162
+ Backup tersimpan di: ./.claude-kit.bak-2026-06-04/
163
+ Backup yang di-cleanup otomatis: <list, kalau ada>
164
+
165
+ Next step yang AI rekomendasikan:
166
+ [kalau ada Tier 4] Paste JALANKAN_KIT.md untuk scan ulang.
167
+ [kalau ada Tier 3] Ikuti Migration Steps di atas.
168
+ [kalau cuma Tier 1/2] Lanjut kerja biasa — gak perlu apa-apa.
169
+ ```
170
+
171
+ Lalu popup interactive:
172
+ > "Mau lanjut ke step apa?
173
+ > 1. Lanjut task sebelumnya (lupakan update, balik kerja)
174
+ > 2. Cek file yang berubah (`git diff ./.claude-kit/`)
175
+ > 3. Rollback (kembali ke versi lama)
176
+ > 4. Selesai (end sesi)
177
+ >
178
+ > Pilih (1/2/3/4, default 1)?"
179
+
180
+ Karena 3-option+ → assume "YES All Project" = pilih **1** kalau staff diam.
181
+
182
+ ---
183
+
184
+ ## Mapping intent staff → langkah
185
+
186
+ | Staff bilang | AI jalankan |
187
+ |--------------|-------------|
188
+ | "v1.2.0 rilis, update dong" | Full workflow step 1-9. |
189
+ | "lintasAI ada versi baru?" | Step 1-3 doang (cek saja, gak update). |
190
+ | "update kit" | Full workflow. |
191
+ | "rollback dong, update tadi bikin error" | Rollback flow: cari folder `.claude-kit.bak-<tanggal>` terbaru, rename `.claude-kit/` jadi `.claude-kit.broken-<tanggal>/`, rename backup jadi `.claude-kit/`, restore versi di `AGENTS.md`. Lapor ke staff. |
192
+ | "update tapi keep file customization saya" | Full workflow + jelasin di summary: "Tenang, manifest sha256 protect file yang kamu edit. Kayak Google Drive sync — file yang kamu modify lokal gak ke-overwrite sama versi cloud." |
193
+ | "kit saya pake versi berapa?" | Step 1 doang. Lapor versi current. |
194
+ | "hapus backup lama" | Cleanup manual: list `.claude-kit.bak-*`, hapus yang > 30 hari atau lebih dari 3 versi terakhir. Lapor space yang di-free. |
195
+
196
+ ---
197
+
198
+ ## Tone & gaya komunikasi
199
+
200
+ - **Senior dev jelasin ke junior staff** — sabar, gak nyinyir, gak pakai jargon kering.
201
+ - **Analogi tools digital populer WAJIB** tiap kali jelasin konsep teknis. Pool analogi: Tokopedia, Shopee, Gojek, WhatsApp, BCA mobile, Excel, Google Drive, Notion, Discord, iPhone, Spotify, Netflix.
202
+ - **Pendek > panjang**. Staff sibuk, gak baca dinding teks.
203
+ - **Konfirmasi sekali di awal**, abis itu jalan terus sampai selesai.
204
+
205
+ ---
206
+
207
+ ## Closing message setelah update
208
+
209
+ Setelah step 9 dieksekusi dan staff jawab popup (atau diam = default), tutup dengan:
210
+
211
+ > "Update kit beres. Kalau ada perilaku AI yang berubah aneh abis ini, paste `JALANKAN_KIT.md` untuk re-sync. Atau bilang ke aku: 'rollback dong'. Aman."
212
+
213
+ End sesi update.
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env node
2
+ // lintasAI CLI launcher - spawns PowerShell scripts
3
+ // Usage: npx lintasai <command> [args]
4
+
5
+ const { spawn } = require("child_process");
6
+ const path = require("path");
7
+ const os = require("os");
8
+
9
+ const KIT_ROOT = path.resolve(__dirname, "..");
10
+
11
+ const COMMANDS = {
12
+ "init": "setup-pola-b.ps1",
13
+ "update": "update-kit.ps1",
14
+ "uninstall": "uninstall.ps1",
15
+ "install-windows": "install-windows.ps1",
16
+ // kit.ps1 subcommands
17
+ "doctor": ["kit.ps1", "doctor"],
18
+ "version": ["kit.ps1", "version"],
19
+ "rollback": ["kit.ps1", "rollback"],
20
+ "setup": ["kit.ps1", "setup"],
21
+ };
22
+
23
+ function showHelp() {
24
+ console.log("");
25
+ console.log("lintasAI CLI - AI workflow kit for Claude Code");
26
+ console.log("");
27
+ console.log("Usage:");
28
+ console.log(" npx @ojokesusu/lintasai <command> [args]");
29
+ console.log("");
30
+ console.log("Commands:");
31
+ console.log(" init Setup kit di project (alias setup-pola-b)");
32
+ console.log(" update Update kit ke versi terbaru");
33
+ console.log(" doctor Verify kit integrity");
34
+ console.log(" version Show kit version");
35
+ console.log(" rollback Rollback ke versi sebelumnya");
36
+ console.log(" uninstall Remove kit dari project");
37
+ console.log("");
38
+ console.log("Examples:");
39
+ console.log(" npx @ojokesusu/lintasai init");
40
+ console.log(" npx @ojokesusu/lintasai update");
41
+ console.log(" npx @ojokesusu/lintasai doctor");
42
+ console.log("");
43
+ console.log("More info: https://github.com/ojokesusu/lintasAI");
44
+ }
45
+
46
+ if (os.platform() !== "win32") {
47
+ console.error("[ERROR] lintasAI saat ini Windows-only.");
48
+ console.error("Cross-platform support coming in v2.0+.");
49
+ console.error("Workaround: Pakai Windows VM atau WSL2.");
50
+ process.exit(1);
51
+ }
52
+
53
+ const command = process.argv[2];
54
+ const args = process.argv.slice(3);
55
+
56
+ if (!command || command === "help" || command === "--help" || command === "-h") {
57
+ showHelp();
58
+ process.exit(0);
59
+ }
60
+
61
+ const target = COMMANDS[command];
62
+ if (!target) {
63
+ console.error("[ERROR] Unknown command: " + command);
64
+ console.error("Run: npx @ojokesusu/lintasai help");
65
+ process.exit(1);
66
+ }
67
+
68
+ // Build powershell command
69
+ let psArgs;
70
+ if (Array.isArray(target)) {
71
+ // kit.ps1 subcommand
72
+ psArgs = ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", path.join(KIT_ROOT, target[0]), target[1], ...args];
73
+ } else {
74
+ // Direct script call
75
+ psArgs = ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", path.join(KIT_ROOT, target), ...args];
76
+ }
77
+
78
+ const child = spawn("powershell.exe", psArgs, { stdio: "inherit" });
79
+ child.on("close", (code) => {
80
+ process.exit(code || 0);
81
+ });
@@ -0,0 +1,162 @@
1
+ # Signed Release lintasAI - GPG Verification
2
+
3
+ Dokumen ini menjelaskan kenapa rilis lintasAI ditandatangani dengan GPG, dan bagaimana owner serta staff memakainya supaya yakin tag yang di-clone benar-benar dari pemilik repo, bukan hasil tampering.
4
+
5
+ ## Kenapa perlu? (3-layer analogi)
6
+
7
+ - **Sehari-hari:** kayak tanda tangan + stempel notaris di akta - mustahil dipalsukan tanpa cap & tanda tangan asli. Kalau ada akta tanpa stempel notaris, kita langsung curiga, kan?
8
+ - **Tools digital populer:** kayak ikon gembok HTTPS di Tokopedia/BCA mobile - browser cek sertifikat valid, kalau invalid muncul warning merah gede. User awam pun langsung waspada.
9
+ - **Konkret di lintasAI:** staff yakin tag `v1.x.y` yang di-clone benar dari owner asli `ojokesusu`, bukan attacker yang compromise akun GitHub. Tanpa signature, siapa pun yang punya akses push ke repo bisa bikin tag palsu yang kelihatan sah.
10
+
11
+ ## Setup GPG (owner - sekali saja)
12
+
13
+ Ini langkah satu kali di mesin owner. Setelah selesai, semua tag berikutnya tinggal sign pakai key yang sama.
14
+
15
+ 1. Install GPG:
16
+ ```powershell
17
+ scoop install gnupg
18
+ # ATAU
19
+ choco install gnupg
20
+ ```
21
+ 2. Generate key:
22
+ ```powershell
23
+ gpg --full-generate-key
24
+ ```
25
+ Pilih `RSA and RSA`, ukuran `4096`, expiry `0` (no expiry) untuk simplicity. Isi nama & email yang sama dengan akun GitHub.
26
+ 3. List & catat KEY_ID:
27
+ ```powershell
28
+ gpg --list-secret-keys --keyid-format LONG
29
+ ```
30
+ Output ada baris `sec rsa4096/ABCD1234EFGH5678 ...` - bagian `ABCD1234EFGH5678` itu KEY_ID-nya.
31
+ 4. Daftarkan ke git:
32
+ ```powershell
33
+ git config --global user.signingkey ABCD1234EFGH5678
34
+ ```
35
+ 5. (Opsional) Auto-sign semua commit, bukan cuma tag:
36
+ ```powershell
37
+ git config --global commit.gpgsign true
38
+ ```
39
+ 6. Export public key:
40
+ ```powershell
41
+ gpg --armor --export ABCD1234EFGH5678 > .github/owner-pubkey.asc
42
+ ```
43
+ 7. Commit pubkey ke repo:
44
+ ```powershell
45
+ git add .github/owner-pubkey.asc
46
+ git commit -m "add owner gpg pubkey for tag verification"
47
+ ```
48
+
49
+ ## Workflow saat release (owner)
50
+
51
+ Setiap rilis baru, tag dibuat dengan flag `-s` (signed):
52
+
53
+ ```powershell
54
+ git tag -s v1.x.y -m "lintasAI v1.x.y - <ringkasan changes>"
55
+ git push origin v1.x.y
56
+ ```
57
+
58
+ Catatan:
59
+ - `git tag -s` = signed tag (pakai GPG key yang sudah didaftarkan).
60
+ - `git tag` tanpa `-s` = unsigned, staff tidak akan bisa verify.
61
+ - Kalau owner lupa pakai `-s`, hapus tag (`git tag -d` + `git push --delete`) lalu bikin ulang dengan `-s`.
62
+
63
+ ## Workflow saat staff first-time (sekali saja)
64
+
65
+ Sekali saja per mesin staff, import pubkey owner supaya GPG tahu key mana yang trusted.
66
+
67
+ 1. Download pubkey dari repo:
68
+ ```powershell
69
+ curl -O https://raw.githubusercontent.com/ojokesusu/lintasAI/main/.github/owner-pubkey.asc
70
+ ```
71
+ 2. Import ke keychain lokal:
72
+ ```powershell
73
+ gpg --import owner-pubkey.asc
74
+ ```
75
+ 3. Tandai sebagai trusted:
76
+ ```powershell
77
+ gpg --edit-key ABCD1234EFGH5678
78
+ ```
79
+ Lalu di prompt GPG: ketik `trust`, pilih `4` (I trust fully), ketik `quit`.
80
+
81
+ ## Workflow saat staff clone/update (tiap kali)
82
+
83
+ Setiap kali pull tag baru, lakukan verify sebelum jalankan kit:
84
+
85
+ ```powershell
86
+ git clone -b v1.x.y https://github.com/ojokesusu/lintasAI.git
87
+ cd lintasAI
88
+ git tag --verify v1.x.y
89
+ ```
90
+
91
+ Interpretasi output:
92
+ - `Good signature from "Owner Name <email>"` -> aman, lanjut install.
93
+ - `BAD signature` -> tag sudah dimodifikasi setelah signing. STOP.
94
+ - `No public key` -> pubkey owner belum di-import. Balik ke step first-time dulu.
95
+ - `gpg: WARNING: This key is not certified...` -> pubkey ter-import tapi belum di-trust. Balik ke step `trust` di first-time.
96
+
97
+ Kalau muncul BAD signature atau anomaly lain: **STOP, jangan install**, lapor owner via Telegram/Signal (jalur out-of-band, bukan via GitHub issue karena issue-nya bisa juga dipalsu).
98
+
99
+ ## Integrasi dengan kit.ps1 (opsional)
100
+
101
+ `update-kit.ps1` bisa auto-verify tag sebelum apply update:
102
+
103
+ ```powershell
104
+ git fetch --tags
105
+ git tag --verify v1.x.y
106
+ if ($LASTEXITCODE -ne 0) {
107
+ throw "Tag signature invalid, aborting update"
108
+ }
109
+ git checkout v1.x.y
110
+ ```
111
+
112
+ Manfaat: staff tidak perlu inget jalankan verify manual, kit sendiri yang enforce.
113
+
114
+ ## Fallback: kalau GPG belum disetup
115
+
116
+ Belum sempat setup GPG? Bisa pakai alternatif manual sementara:
117
+
118
+ 1. Owner publish SHA256 commit hash tiap tag di `README.md`:
119
+ ```
120
+ v1.0.0 -> commit a1b2c3d4e5f6...
121
+ v1.0.1 -> commit f6e5d4c3b2a1...
122
+ ```
123
+ 2. Staff verify manual:
124
+ ```powershell
125
+ git rev-parse v1.x.y
126
+ # bandingkan output dengan yang owner publish
127
+ ```
128
+ 3. Migrate ke GPG begitu sempat - SHA256 manual rentan kalau attacker juga modifikasi README.
129
+
130
+ ## Troubleshooting
131
+
132
+ - **`gpg: signing failed: Inappropriate ioctl for device`** -> environment GPG tidak detect TTY. Set:
133
+ ```powershell
134
+ $env:GPG_TTY = $(tty)
135
+ ```
136
+ Di Linux/Mac: `export GPG_TTY=$(tty)`. Lalu retry `git tag -s ...`.
137
+ - **Windows: gpg-agent macet** -> restart agent:
138
+ ```powershell
139
+ gpgconf --kill gpg-agent
140
+ ```
141
+ Lalu retry. Kalau masih, restart shell/PowerShell.
142
+ - **`gpg: skipped "KEY_ID": No secret key`** -> KEY_ID salah ketik atau key belum di-generate. Cek ulang `gpg --list-secret-keys --keyid-format LONG`.
143
+ - **Tag sudah dibuat tanpa `-s`** -> hapus & ulang:
144
+ ```powershell
145
+ git tag -d v1.x.y
146
+ git push origin :refs/tags/v1.x.y
147
+ git tag -s v1.x.y -m "..."
148
+ git push origin v1.x.y
149
+ ```
150
+
151
+ ## Threat model singkat
152
+
153
+ - **ATTACK:** akun GitHub owner di-compromise (password leak, session token curian, dst), attacker push tag `v1.x.y` berisi backdoor.
154
+ - **DEFENSE:** tag tidak signed (attacker tidak punya private key GPG owner), atau signed dengan key beda -> `git tag --verify` fail -> staff tidak install.
155
+ - **LIMITATION:** kalau attacker juga curi private key GPG owner (misal laptop owner kena RAT) = game over, signature sah dari sisi GPG.
156
+ - **HARDENING:** owner pakai hardware key (YubiKey/Nitrokey) - private key tidak pernah keluar dari device, attacker yang remote-compromise laptop tetap tidak bisa sign tanpa colok device fisik + tap.
157
+
158
+ ## Catatan operasional
159
+
160
+ - Pubkey di `.github/owner-pubkey.asc` aman untuk publik, memang harus bisa diakses semua staff.
161
+ - **Private key TIDAK PERNAH** masuk repo, tidak pernah di-share, tidak pernah dibackup ke cloud tanpa enkripsi tambahan.
162
+ - Kalau owner curiga private key bocor: revoke segera (`gpg --gen-revoke`), publish revocation certificate, bikin key baru, update `.github/owner-pubkey.asc`, announce ke semua staff via jalur out-of-band.
@@ -0,0 +1,225 @@
1
+ <#
2
+ .SYNOPSIS
3
+ install-windows.ps1 - Installer paket Claude config untuk Windows
4
+ .DESCRIPTION
5
+ Menyalin file paket ke %USERPROFILE%\.claude\ dengan backup otomatis
6
+ bila file tujuan sudah ada (format .backup-yyyyMMdd-HHmmss).
7
+ .PARAMETER DryRun
8
+ Hanya tampilkan rencana aksi tanpa menyalin/menghapus file apapun.
9
+ .PARAMETER Force
10
+ Lewati prompt konfirmasi saat ada file existing yang akan ditimpa.
11
+ .NOTES
12
+ Versi : 1.1
13
+ Tanggal: 2026-05-30
14
+ Run : powershell -ExecutionPolicy Bypass -File .\install-windows.ps1
15
+ Catatan: Kompatibel PowerShell 5.1 (tanpa operator && / ||).
16
+ #>
17
+
18
+ [CmdletBinding()]
19
+ param(
20
+ [switch]$DryRun,
21
+ [switch]$Force
22
+ )
23
+
24
+ $ErrorActionPreference = 'Stop'
25
+
26
+ # ---- Cek versi PowerShell ----
27
+ if ($PSVersionTable.PSVersion.Major -lt 5) {
28
+ Write-Host "ERROR: Script ini butuh PowerShell 5.1+. Versi kamu: $($PSVersionTable.PSVersion)" -ForegroundColor Red
29
+ exit 1
30
+ }
31
+
32
+ # ---- Konfigurasi dasar ----
33
+ $ClaudeDir = Join-Path $env:USERPROFILE '.claude'
34
+ $TemplatesDir = Join-Path $ClaudeDir 'templates'
35
+ $Timestamp = Get-Date -Format 'yyyyMMdd-HHmmss'
36
+
37
+ # Tentukan folder script (guard kalau dijalankan via Invoke-Expression / pipe)
38
+ $ScriptDir = $null
39
+ if ($PSScriptRoot) {
40
+ $ScriptDir = $PSScriptRoot
41
+ } elseif ($MyInvocation.MyCommand.Path) {
42
+ $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
43
+ } else {
44
+ $ScriptDir = (Get-Location).Path
45
+ Write-Host "PERINGATAN: Tidak bisa deteksi folder script otomatis." -ForegroundColor Yellow
46
+ Write-Host " Pakai folder kerja saat ini: $ScriptDir" -ForegroundColor Yellow
47
+ Write-Host " Pastikan kamu sudah cd ke folder paket sebelum jalankan." -ForegroundColor Yellow
48
+ Write-Host ""
49
+ }
50
+
51
+ # Counter ringkasan
52
+ $okCount = 0
53
+ $bakCount = 0
54
+ $missCount = 0
55
+
56
+ Write-Host ""
57
+ Write-Host "=== Installer paket Claude (Windows) ===" -ForegroundColor Cyan
58
+ Write-Host "Sumber : $ScriptDir"
59
+ Write-Host "Target : $ClaudeDir"
60
+ if ($DryRun) {
61
+ Write-Host "Mode : DRY-RUN (tidak ada file yang benar-benar disalin)" -ForegroundColor Yellow
62
+ }
63
+ Write-Host ""
64
+
65
+ # ---- Step 1 & 2: pastikan folder tujuan ada ----
66
+ function Confirm-Directory {
67
+ param([string]$Path)
68
+ if (Test-Path $Path) { return }
69
+ if ($DryRun) {
70
+ Write-Host "[DRY] Akan dibuat folder: $Path" -ForegroundColor Yellow
71
+ return
72
+ }
73
+ try {
74
+ New-Item -ItemType Directory -Force -Path $Path | Out-Null
75
+ Write-Host "DIBUAT $Path" -ForegroundColor Green
76
+ } catch {
77
+ Write-Host "GAGAL bikin folder $Path : $_" -ForegroundColor Red
78
+ Write-Host " Cek permission write ke $env:USERPROFILE." -ForegroundColor Red
79
+ exit 1
80
+ }
81
+ }
82
+
83
+ Confirm-Directory -Path $ClaudeDir
84
+ Confirm-Directory -Path $TemplatesDir
85
+
86
+ # ---- Mark-of-the-Web unblock (cegah error 'script tidak digital signed' setelah download) ----
87
+ if (-not $DryRun) {
88
+ try {
89
+ Get-ChildItem $ScriptDir -Recurse -File -ErrorAction SilentlyContinue | Unblock-File -ErrorAction SilentlyContinue
90
+ Write-Host "OK Mark-of-the-Web di-unblock untuk file di folder paket." -ForegroundColor Green
91
+ } catch {
92
+ Write-Host "PERINGATAN: Unblock-File gagal: $_ (script tetap lanjut)" -ForegroundColor Yellow
93
+ }
94
+ }
95
+
96
+ # ---- Step 3: mapping file source -> destination ----
97
+ # Catatan: CLAUDE_universal_v1.md di-RENAME jadi CLAUDE.md saat di-install.
98
+ # Pola A user dapat 4 aturan dokumentasi tim profesional + PROJECT_LIFECYCLE_PROMPT (kickoff/bootstrap/update/migration unified) + 3 file template (_PATTERNS, _EXAMPLE, architecture_auto).
99
+ $mapping = @(
100
+ @{ Src = 'CLAUDE_universal_v1.md'; Dst = (Join-Path $ClaudeDir 'CLAUDE.md') },
101
+ @{ Src = 'PROJECT_LIFECYCLE_PROMPT_v1.md'; Dst = (Join-Path $ClaudeDir 'PROJECT_LIFECYCLE_PROMPT_v1.md') },
102
+ @{ Src = 'TEAM_ROLLOUT_GUIDE_v1.md'; Dst = (Join-Path $ClaudeDir 'TEAM_ROLLOUT_GUIDE_v1.md') },
103
+ @{ Src = 'templates\architecture.md'; Dst = (Join-Path $TemplatesDir 'architecture.md') },
104
+ @{ Src = 'templates\glossary.md'; Dst = (Join-Path $TemplatesDir 'glossary.md') },
105
+ @{ Src = 'templates\_PATTERNS.md'; Dst = (Join-Path $TemplatesDir '_PATTERNS.md') },
106
+ @{ Src = 'templates\_EXAMPLE.md'; Dst = (Join-Path $TemplatesDir '_EXAMPLE.md') },
107
+ @{ Src = 'templates\architecture_auto.md'; Dst = (Join-Path $TemplatesDir 'architecture_auto.md') }
108
+ )
109
+
110
+ # Konfirmasi sekali di awal kalau ada existing file (kecuali -Force / -DryRun)
111
+ if (-not $Force -and -not $DryRun) {
112
+ $existing = @()
113
+ foreach ($item in $mapping) {
114
+ if (Test-Path $item.Dst) { $existing += $item.Dst }
115
+ }
116
+ if ($existing.Count -gt 0) {
117
+ Write-Host "PERHATIAN: $($existing.Count) file tujuan sudah ada dan akan ditimpa." -ForegroundColor Yellow
118
+ Write-Host " Backup otomatis dibuat dengan akhiran .backup-$Timestamp" -ForegroundColor Yellow
119
+ foreach ($e in $existing) {
120
+ Write-Host " - $e" -ForegroundColor Yellow
121
+ }
122
+ Write-Host ""
123
+ # Wrap Read-Host di try/catch — gracefully handle NonInteractive shell.
124
+ # Default ke 'N' (jangan overwrite file existing tanpa konfirmasi user).
125
+ $answer = 'N'
126
+ try {
127
+ $answer = Read-Host "Lanjut install? (Y/N)"
128
+ } catch {
129
+ Write-Host "INFO: Shell NonInteractive terdeteksi. Install tidak dilanjutkan (default safe)." -ForegroundColor Yellow
130
+ Write-Host " Pakai -Force kalau memang mau timpa, atau jalankan di PowerShell window." -ForegroundColor Yellow
131
+ $answer = 'N'
132
+ }
133
+ if ($answer -notmatch '^[Yy]') {
134
+ Write-Host "Dibatalkan oleh user. Tidak ada file yang diubah." -ForegroundColor Yellow
135
+ exit 0
136
+ }
137
+ Write-Host ""
138
+ }
139
+ }
140
+
141
+ foreach ($item in $mapping) {
142
+ $srcPath = Join-Path $ScriptDir $item.Src
143
+ $dstPath = $item.Dst
144
+ $label = $item.Src
145
+
146
+ # Source hilang -> tandai MISSING
147
+ if (-not (Test-Path $srcPath)) {
148
+ Write-Host "MISSING $label (tidak ditemukan di folder paket)" -ForegroundColor Red
149
+ $missCount++
150
+ continue
151
+ }
152
+
153
+ # Dry-run: cuma log rencana
154
+ if ($DryRun) {
155
+ if (Test-Path $dstPath) {
156
+ Write-Host "[DRY] BACKUP $dstPath -> $dstPath.backup-$Timestamp" -ForegroundColor Yellow
157
+ Write-Host "[DRY] INSTALL $label -> $dstPath" -ForegroundColor Yellow
158
+ } else {
159
+ Write-Host "[DRY] INSTALL $label -> $dstPath" -ForegroundColor Yellow
160
+ }
161
+ continue
162
+ }
163
+
164
+ # Destination sudah ada -> backup dulu (pakai .backup-<ts>, bukan .bak)
165
+ if (Test-Path $dstPath) {
166
+ $bakPath = "$dstPath.backup-$Timestamp"
167
+ try {
168
+ Copy-Item -Path $dstPath -Destination $bakPath -Force
169
+ Write-Host "BACKUP $dstPath -> $bakPath" -ForegroundColor Yellow
170
+ $bakCount++
171
+ } catch {
172
+ Write-Host "GAGAL backup $dstPath -> $bakPath : $_" -ForegroundColor Red
173
+ $missCount++
174
+ continue
175
+ }
176
+ }
177
+
178
+ # Copy source ke destination (overwrite kalau perlu)
179
+ try {
180
+ Copy-Item -Path $srcPath -Destination $dstPath -Force
181
+ Write-Host "OK $label -> $dstPath" -ForegroundColor Green
182
+ $okCount++
183
+ } catch {
184
+ Write-Host "GAGAL copy $label : $_" -ForegroundColor Red
185
+ $missCount++
186
+ }
187
+ }
188
+
189
+ # ---- Step 4: ringkasan & panduan ----
190
+ Write-Host ""
191
+ Write-Host "=== Ringkasan ===" -ForegroundColor Cyan
192
+ if ($DryRun) {
193
+ Write-Host "Mode DRY-RUN: tidak ada file yang benar-benar disalin." -ForegroundColor Yellow
194
+ Write-Host "Jalankan ulang tanpa -DryRun untuk eksekusi sungguhan." -ForegroundColor Yellow
195
+ Write-Host ""
196
+ exit 0
197
+ }
198
+
199
+ $totalSrc = $mapping.Count
200
+ Write-Host ("Total file di paket : {0}" -f $totalSrc) -ForegroundColor Cyan
201
+ Write-Host ("Ter-install : {0}" -f $okCount) -ForegroundColor Green
202
+ Write-Host ("Di-backup (timpa) : {0}" -f $bakCount) -ForegroundColor Yellow
203
+ Write-Host ("Missing/error : {0}" -f $missCount) -ForegroundColor Red
204
+ Write-Host ""
205
+
206
+ Write-Host "Langkah berikutnya:" -ForegroundColor Cyan
207
+ Write-Host " 1. Buka folder $ClaudeDir untuk memastikan file ter-install."
208
+ Write-Host " 2. File backup berakhiran .backup-$Timestamp adalah salinan file lama;"
209
+ Write-Host " hapus kalau sudah yakin install ini OK."
210
+ Write-Host " 3. Buka project pakai Claude Code -> CLAUDE.md akan otomatis ter-load."
211
+ Write-Host " Verifikasi dengan buka langsung file $ClaudeDir\CLAUDE.md,"
212
+ Write-Host " atau tanya AI: 'Kamu baca aturan global dari file apa?'"
213
+ Write-Host " 4. Baca README untuk cara pakai PROJECT_LIFECYCLE_PROMPT_v1.md"
214
+ Write-Host " (Stage A: Kickoff / Stage B: Bootstrap Docs / Stage C: Update Docs / Stage D: Migration)."
215
+ Write-Host ""
216
+
217
+ if ($missCount -gt 0) {
218
+ Write-Host ("PERINGATAN: {0} file ter-install, {1} file gagal/missing." -f $okCount, $missCount) -ForegroundColor Red
219
+ Write-Host " Install partial -- cek pesan MISSING/GAGAL di atas," -ForegroundColor Red
220
+ Write-Host " lalu jalankan ulang setelah file lengkap." -ForegroundColor Red
221
+ exit 1
222
+ }
223
+
224
+ Write-Host "Selesai. Selamat ngoding!" -ForegroundColor Green
225
+ exit 0