laporan-generator 2.6.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.
Files changed (109) hide show
  1. package/.agents/skills/laporan-generator/SKILL.md +132 -0
  2. package/.agents/skills/laporan-generator/agents/openai.yaml +3 -0
  3. package/.agents/skills/laporan-generator/references/campus-guide.md +120 -0
  4. package/.agents/skills/laporan-generator/references/metadata-schema.md +76 -0
  5. package/.agents/skills/laporan-generator/references/preset-schema.md +79 -0
  6. package/.agents/skills/laporan-generator/references/syntax-cheatsheet.md +122 -0
  7. package/.agents/skills/laporan-generator/references/template-guide.md +100 -0
  8. package/.agents/skills/laporan-generator/references/troubleshooting.md +105 -0
  9. package/.agents/skills/laporan-generator/resources/Makefile +90 -0
  10. package/.agents/skills/laporan-generator/resources/apa.csl +2273 -0
  11. package/.agents/skills/laporan-generator/resources/build-docx.sh +122 -0
  12. package/.agents/skills/laporan-generator/resources/build.sh +102 -0
  13. package/.agents/skills/laporan-generator/resources/chapters/bab1-pendahuluan.md +60 -0
  14. package/.agents/skills/laporan-generator/resources/chapters/bab2-tinjauan-pustaka.md +83 -0
  15. package/.agents/skills/laporan-generator/resources/chapters/bab3-metodologi.md +116 -0
  16. package/.agents/skills/laporan-generator/resources/chapters/bab4-hasil-dan-pembahasan.md +93 -0
  17. package/.agents/skills/laporan-generator/resources/chapters/bab5-penutup.md +27 -0
  18. package/.agents/skills/laporan-generator/resources/cover.md +50 -0
  19. package/.agents/skills/laporan-generator/resources/docx.lua +416 -0
  20. package/.agents/skills/laporan-generator/resources/laporan +464 -0
  21. package/.agents/skills/laporan-generator/resources/laporan.ps1 +552 -0
  22. package/.agents/skills/laporan-generator/resources/logo.jpg +0 -0
  23. package/.agents/skills/laporan-generator/resources/metadata.yml +35 -0
  24. package/.agents/skills/laporan-generator/resources/presets/itb-ta.yml +27 -0
  25. package/.agents/skills/laporan-generator/resources/presets/its-skripsi.yml +26 -0
  26. package/.agents/skills/laporan-generator/resources/presets/skripsi-4433.yml +26 -0
  27. package/.agents/skills/laporan-generator/resources/presets/standard.yml +26 -0
  28. package/.agents/skills/laporan-generator/resources/presets/ugm-skripsi.yml +26 -0
  29. package/.agents/skills/laporan-generator/resources/presets/ui-skripsi.yml +26 -0
  30. package/.agents/skills/laporan-generator/resources/presets/unpad-skripsi.yml +27 -0
  31. package/.agents/skills/laporan-generator/resources/reference.docx +0 -0
  32. package/.agents/skills/laporan-generator/resources/references.bib +115 -0
  33. package/.agents/skills/laporan-generator/resources/scripts/bundle.py +75 -0
  34. package/.agents/skills/laporan-generator/resources/scripts/docx-pagenum.py +192 -0
  35. package/.agents/skills/laporan-generator/resources/scripts/finalize-docx.py +291 -0
  36. package/.agents/skills/laporan-generator/resources/scripts/make-reference-docx.py +670 -0
  37. package/.agents/skills/laporan-generator/resources/scripts/report-doctor.py +211 -0
  38. package/.agents/skills/laporan-generator/resources/scripts/report-stats.py +149 -0
  39. package/.agents/skills/laporan-generator/resources/scripts/scan-preset.py +311 -0
  40. package/.agents/skills/laporan-generator/resources/scripts/setup-deps.ps1 +152 -0
  41. package/.agents/skills/laporan-generator/resources/scripts/setup-deps.sh +113 -0
  42. package/.agents/skills/laporan-generator/resources/scripts/test_scripts.py +128 -0
  43. package/.agents/skills/laporan-generator/resources/scripts/validate-preset.py +166 -0
  44. package/.agents/skills/laporan-generator/resources/template.typ +394 -0
  45. package/.agents/skills/laporan-generator/scripts/build.sh +78 -0
  46. package/.agents/skills/laporan-generator/scripts/bundle.py +75 -0
  47. package/.agents/skills/laporan-generator/scripts/docx-pagenum.py +192 -0
  48. package/.agents/skills/laporan-generator/scripts/finalize-docx.py +152 -0
  49. package/.agents/skills/laporan-generator/scripts/laporan +447 -0
  50. package/.agents/skills/laporan-generator/scripts/laporan.ps1 +529 -0
  51. package/.agents/skills/laporan-generator/scripts/make-reference-docx.py +630 -0
  52. package/.agents/skills/laporan-generator/scripts/report-doctor.py +211 -0
  53. package/.agents/skills/laporan-generator/scripts/report-stats.py +149 -0
  54. package/.agents/skills/laporan-generator/scripts/scan-preset.py +311 -0
  55. package/.agents/skills/laporan-generator/scripts/setup-deps.ps1 +152 -0
  56. package/.agents/skills/laporan-generator/scripts/setup-deps.sh +113 -0
  57. package/.agents/skills/laporan-generator/scripts/test_scripts.py +103 -0
  58. package/.agents/skills/laporan-generator/scripts/validate-preset.py +166 -0
  59. package/.agents/workflows/laporan-generator.md +8 -0
  60. package/LICENSE +21 -0
  61. package/Makefile +90 -0
  62. package/README.md +389 -0
  63. package/apa.csl +2273 -0
  64. package/bin/laporan-generator.js +71 -0
  65. package/build-docx.sh +122 -0
  66. package/build.sh +102 -0
  67. package/chapters/bab1-pendahuluan.md +60 -0
  68. package/chapters/bab2-tinjauan-pustaka.md +83 -0
  69. package/chapters/bab3-metodologi.md +116 -0
  70. package/chapters/bab4-hasil-dan-pembahasan.md +93 -0
  71. package/chapters/bab5-penutup.md +27 -0
  72. package/cover.md +50 -0
  73. package/docs/campus-guide.md +120 -0
  74. package/docs/metadata-schema.md +76 -0
  75. package/docs/preset-schema.md +79 -0
  76. package/docs/syntax-cheatsheet.md +122 -0
  77. package/docs/template-guide.md +100 -0
  78. package/docs/troubleshooting.md +105 -0
  79. package/docx.lua +416 -0
  80. package/laporan +464 -0
  81. package/laporan.ps1 +552 -0
  82. package/lib/init.js +118 -0
  83. package/lib/setup.js +33 -0
  84. package/lib/sync-hosts.js +194 -0
  85. package/lib/uninstall.js +123 -0
  86. package/logo.jpg +0 -0
  87. package/metadata.yml +35 -0
  88. package/package.json +65 -0
  89. package/presets/itb-ta.yml +27 -0
  90. package/presets/its-skripsi.yml +26 -0
  91. package/presets/skripsi-4433.yml +26 -0
  92. package/presets/standard.yml +26 -0
  93. package/presets/ugm-skripsi.yml +26 -0
  94. package/presets/ui-skripsi.yml +26 -0
  95. package/presets/unpad-skripsi.yml +27 -0
  96. package/reference.docx +0 -0
  97. package/references.bib +115 -0
  98. package/scripts/bundle.py +75 -0
  99. package/scripts/docx-pagenum.py +192 -0
  100. package/scripts/finalize-docx.py +291 -0
  101. package/scripts/make-reference-docx.py +670 -0
  102. package/scripts/report-doctor.py +211 -0
  103. package/scripts/report-stats.py +149 -0
  104. package/scripts/scan-preset.py +311 -0
  105. package/scripts/setup-deps.ps1 +152 -0
  106. package/scripts/setup-deps.sh +113 -0
  107. package/scripts/test_scripts.py +128 -0
  108. package/scripts/validate-preset.py +166 -0
  109. package/template.typ +394 -0
@@ -0,0 +1,529 @@
1
+ # ==============================================================================
2
+ # Laporan Generator CLI Helper for Windows PowerShell (.\laporan.ps1)
3
+ # ==============================================================================
4
+ param (
5
+ [Parameter(Position=0)]
6
+ [string]$Command = "help",
7
+ [Parameter(Position=1)]
8
+ [string]$SubCommand = "",
9
+ [Parameter(Position=2)]
10
+ [string]$Arg1 = "",
11
+ [Parameter(Position=3)]
12
+ [string]$Arg2 = ""
13
+ )
14
+
15
+ $ErrorActionPreference = "Stop"
16
+
17
+ function Show-Banner {
18
+ Write-Host " ========================================================" -ForegroundColor Cyan
19
+ Write-Host " LAPORAN GENERATOR CLI v2.6.0 " -ForegroundColor Cyan
20
+ Write-Host " Otomatisasi Dokumen Akademik (Typst + DOCX Engine) " -ForegroundColor Cyan
21
+ Write-Host " ========================================================" -ForegroundColor Cyan
22
+ Write-Host ""
23
+ }
24
+
25
+ function Show-Help {
26
+ Show-Banner
27
+ Write-Host "Penggunaan: .\laporan.ps1 <perintah>" -ForegroundColor White
28
+ Write-Host ""
29
+ Write-Host "Perintah yang Tersedia:" -ForegroundColor White
30
+ Write-Host " build Kompilasi PDF dan DOCX sekaligus" -ForegroundColor Green
31
+ Write-Host " pdf Kompilasi dokumen PDF (via Typst)" -ForegroundColor Green
32
+ Write-Host " docx Kompilasi dokumen Microsoft Word (.docx)" -ForegroundColor Green
33
+ Write-Host " init Wizard interaktif untuk konfigurasi awal metadata" -ForegroundColor Green
34
+ Write-Host " preset Kelola preset format kampus (list/show/apply/validate/diff/scan)" -ForegroundColor Green
35
+ Write-Host " stats Analisis statistik kata, halaman, gambar, dan durasi baca" -ForegroundColor Green
36
+ Write-Host " doctor Audit kesehatan proyek (broken images, sitasi hilang, dll.)" -ForegroundColor Green
37
+ Write-Host " bundle Kemas seluruh laporan (PDF, DOCX, MD) menjadi arsip zip" -ForegroundColor Green
38
+ Write-Host " setup Pasang dependensi sistem otomatis Windows (Typst, Pandoc, Magick)" -ForegroundColor Green
39
+ Write-Host " sync-skills Sinkronkan skill AI agent ke Antigravity, Claude, Gemini, Grok" -ForegroundColor Green
40
+ Write-Host " check Audit dependensi sistem dan struktur proyek" -ForegroundColor Green
41
+ Write-Host " test Jalankan suite pengujian otomatis" -ForegroundColor Green
42
+ Write-Host " view Buka dokumen Laporan.pdf di PDF viewer" -ForegroundColor Green
43
+ Write-Host " watch Pantau perubahan berkas dan auto-rebuild" -ForegroundColor Green
44
+ Write-Host " clean Bersihkan berkas output dan direktori sementara" -ForegroundColor Green
45
+ Write-Host " help Tampilkan panduan bantuan ini" -ForegroundColor Green
46
+ Write-Host ""
47
+ Write-Host "Contoh:" -ForegroundColor Yellow
48
+ Write-Host " .\laporan.ps1 build"
49
+ Write-Host " .\laporan.ps1 stats"
50
+ Write-Host " .\laporan.ps1 preset list"
51
+ Write-Host " .\laporan.ps1 preset apply itb-ta"
52
+ }
53
+
54
+ function Cmd-Check {
55
+ Show-Banner
56
+ Write-Host "[1/2] Memeriksa Dependensi Sistem..." -ForegroundColor Blue
57
+
58
+ $pyFound = Get-Command "python" -ErrorAction SilentlyContinue
59
+ if (-not $pyFound) { $pyFound = Get-Command "python3" -ErrorAction SilentlyContinue }
60
+
61
+ $imFound = Get-Command "magick" -ErrorAction SilentlyContinue
62
+ if (-not $imFound) { $imFound = Get-Command "convert" -ErrorAction SilentlyContinue }
63
+
64
+ $deps = @(
65
+ @{ Name="Pandoc"; Cmd="pandoc"; Found=(Get-Command "pandoc" -ErrorAction SilentlyContinue); Req=$true },
66
+ @{ Name="Typst"; Cmd="typst"; Found=(Get-Command "typst" -ErrorAction SilentlyContinue); Req=$true },
67
+ @{ Name="ImageMagick"; Cmd="magick/convert"; Found=$imFound; Req=$false },
68
+ @{ Name="Python 3"; Cmd="python/python3"; Found=$pyFound; Req=$true },
69
+ @{ Name="LibreOffice"; Cmd="soffice"; Found=(Get-Command "soffice" -ErrorAction SilentlyContinue); Req=$false }
70
+ )
71
+
72
+ $allOk = $true
73
+ foreach ($d in $deps) {
74
+ if ($d.Found) {
75
+ Write-Host " [OK] $($d.Name) ($($d.Cmd)) terpasang: $($d.Found.Source)" -ForegroundColor Green
76
+ } else {
77
+ if ($d.Req) {
78
+ Write-Host " [FAIL] $($d.Name) ($($d.Cmd)) TIDAK DITEMUKAN (Wajib)" -ForegroundColor Red
79
+ $allOk = $false
80
+ } else {
81
+ Write-Host " [INFO] $($d.Name) ($($d.Cmd)) tidak ditemukan (Opsional)" -ForegroundColor Yellow
82
+ }
83
+ }
84
+ }
85
+
86
+ Write-Host ""
87
+ Write-Host "[2/2] Memeriksa Berkas Proyek..." -ForegroundColor Blue
88
+ $files = @("metadata.yml", "cover.md", "template.typ", "reference.docx", "references.bib", "docx.lua")
89
+ foreach ($f in $files) {
90
+ if (Test-Path $f) {
91
+ Write-Host " [OK] Berkas $f ditemukan" -ForegroundColor Green
92
+ } else {
93
+ Write-Host " [FAIL] Berkas $f tidak ditemukan" -ForegroundColor Red
94
+ $allOk = $false
95
+ }
96
+ }
97
+
98
+ $dirs = @("presets", "chapters")
99
+ foreach ($d in $dirs) {
100
+ if (Test-Path $d) {
101
+ Write-Host " [OK] Direktori $d ditemukan" -ForegroundColor Green
102
+ } else {
103
+ Write-Host " [FAIL] Direktori $d tidak ditemukan" -ForegroundColor Red
104
+ $allOk = $false
105
+ }
106
+ }
107
+
108
+ Write-Host ""
109
+ if ($allOk) {
110
+ Write-Host "Semua dependensi dan berkas proyek lengkap dan siap digunakan!" -ForegroundColor Green
111
+ } else {
112
+ Write-Host "Ada beberapa komponen yang kurang. Gunakan Docker jika ingin bebas instalasi lokal." -ForegroundColor Yellow
113
+ }
114
+ }
115
+
116
+ function Cmd-Build-PDF {
117
+ Show-Banner
118
+ Write-Host "Membangun Dokumen PDF (Typst Engine)..." -ForegroundColor Blue
119
+
120
+ $inputFiles = @("cover.md") + (Get-ChildItem -Path "chapters" -Filter "bab*.md" | Sort-Object Name | ForEach-Object { $_.FullName })
121
+ $presetOpt = ""
122
+ if (Test-Path "metadata.yml") {
123
+ $content = Get-Content "metadata.yml" -Raw
124
+ if ($content -match "(?:preset|margin_preset)\s*:\s*[`"']?([a-zA-Z0-9_-]+)[`"']?") {
125
+ $presetName = $matches[1]
126
+ if (Test-Path "presets\$presetName.yml") {
127
+ $presetOpt = "--metadata-file=presets\$presetName.yml"
128
+ }
129
+ }
130
+ }
131
+
132
+ $pandocArgs = @(
133
+ $inputFiles,
134
+ "--template=template.typ",
135
+ $presetOpt,
136
+ "--metadata-file=metadata.yml",
137
+ "--citeproc",
138
+ "--bibliography=references.bib",
139
+ "--csl=apa.csl",
140
+ "--metadata=reference-section-title=DAFTAR PUSTAKA",
141
+ "--top-level-division=chapter",
142
+ "--pdf-engine=typst",
143
+ "--no-highlight",
144
+ "-o", "Laporan.pdf"
145
+ ) | Where-Object { $_ -ne "" }
146
+
147
+ & pandoc $pandocArgs
148
+ if ($LASTEXITCODE -eq 0) {
149
+ Write-Host ""
150
+ Write-Host "=== PDF BERHASIL DIBUAT ===" -ForegroundColor Green
151
+ Write-Host "Lokasi: $(Get-Location)\Laporan.pdf" -ForegroundColor Cyan
152
+ } else {
153
+ Write-Host "[ERROR] Kompilasi PDF gagal." -ForegroundColor Red
154
+ }
155
+ }
156
+
157
+ function Cmd-Build-DOCX {
158
+ Show-Banner
159
+ Write-Host "Membangun Dokumen Microsoft Word (DOCX Multi-Pass)..." -ForegroundColor Blue
160
+
161
+ if (-not (Test-Path "chapters")) {
162
+ Write-Host "[ERROR] Direktori chapters/ tidak ditemukan." -ForegroundColor Red
163
+ return
164
+ }
165
+
166
+ $pyCmd = if (Get-Command "python3" -ErrorAction SilentlyContinue) { "python3" } elseif (Get-Command "python" -ErrorAction SilentlyContinue) { "python" } else { "" }
167
+ if (-not $pyCmd) {
168
+ Write-Host "[ERROR] Python 3 dibutuhkan untuk memproses DOCX." -ForegroundColor Red
169
+ return
170
+ }
171
+
172
+ $inputFiles = @("cover.md") + (Get-ChildItem -Path "chapters" -Filter "bab*.md" | Sort-Object Name | ForEach-Object { $_.FullName })
173
+ $presetOpt = ""
174
+ if (Test-Path "metadata.yml") {
175
+ $content = Get-Content "metadata.yml" -Raw
176
+ if ($content -match "(?:preset|margin_preset)\s*:\s*[`"']?([a-zA-Z0-9_-]+)[`"']?") {
177
+ $presetName = $matches[1]
178
+ if (Test-Path "presets\$presetName.yml") {
179
+ $presetOpt = "--metadata-file=presets\$presetName.yml"
180
+ }
181
+ }
182
+ }
183
+
184
+ $tmpDocx = [System.IO.Path]::GetTempFileName() + ".docx"
185
+ $sectDocx = [System.IO.Path]::GetTempFileName() + ".docx"
186
+
187
+ try {
188
+ $pandocArgs = @(
189
+ $inputFiles,
190
+ $presetOpt,
191
+ "--metadata-file=metadata.yml",
192
+ "--citeproc",
193
+ "--bibliography=references.bib",
194
+ "--csl=apa.csl",
195
+ "--metadata=reference-section-title=DAFTAR PUSTAKA",
196
+ "--top-level-division=chapter",
197
+ "--reference-doc=reference.docx",
198
+ "--lua-filter=docx.lua",
199
+ "-o", $tmpDocx
200
+ ) | Where-Object { $_ -ne "" }
201
+
202
+ & pandoc $pandocArgs
203
+ if ($LASTEXITCODE -ne 0) {
204
+ Write-Host "[ERROR] Kompilasi Pandoc ke DOCX gagal." -ForegroundColor Red
205
+ return
206
+ }
207
+
208
+ & $pyCmd scripts/finalize-docx.py $tmpDocx $sectDocx
209
+ & $pyCmd scripts/docx-pagenum.py $sectDocx Laporan.docx
210
+
211
+ if (Test-Path "Laporan.docx") {
212
+ Write-Host ""
213
+ Write-Host "=== DOCX BERHASIL DIBUAT ===" -ForegroundColor Green
214
+ Write-Host "Lokasi: $(Get-Location)\Laporan.docx" -ForegroundColor Cyan
215
+ }
216
+ } finally {
217
+ Remove-Item -Force -ErrorAction SilentlyContinue $tmpDocx, $sectDocx
218
+ }
219
+ }
220
+
221
+ function Cmd-Build {
222
+ Show-Banner
223
+ Write-Host "[1/2] Membangun Dokumen PDF (Typst Engine)..." -ForegroundColor Blue
224
+ Cmd-Build-PDF
225
+ Write-Host ""
226
+ Write-Host "[2/2] Membangun Dokumen Microsoft Word (DOCX Multi-Pass)..." -ForegroundColor Blue
227
+ Cmd-Build-DOCX
228
+ Write-Host ""
229
+ Write-Host "Dokumen PDF dan DOCX berhasil diproses!" -ForegroundColor Green
230
+ }
231
+
232
+ function Escape-Yaml {
233
+ param ([string]$Val)
234
+ if (-not $Val) { return "" }
235
+ $Val = $Val -replace "\\", "\\\\"
236
+ $Val = $Val -replace '"', '\"'
237
+ $Val = $Val -replace "`r", ""
238
+ $Val = $Val -replace "`n", " "
239
+ return $Val
240
+ }
241
+
242
+ function Cmd-Init {
243
+ Show-Banner
244
+ Write-Host "Wizard Konfigurasi Laporan Akademik (Windows PowerShell)" -ForegroundColor Cyan
245
+ Write-Host "Isi data di bawah ini (tekan Enter untuk memakai nilai default):"
246
+ Write-Host ""
247
+
248
+ $in_title = Read-Host "Judul Laporan [LAPORAN PROYEK AKADEMIK]"
249
+ if (-not $in_title) { $in_title = "LAPORAN PROYEK AKADEMIK" }
250
+
251
+ $in_subtitle = Read-Host "Subjudul [DOKUMENTASI DAN ANALISIS IMPLEMENTASI]"
252
+ if (-not $in_subtitle) { $in_subtitle = "DOKUMENTASI DAN ANALISIS IMPLEMENTASI" }
253
+
254
+ $in_course = Read-Host "Mata Kuliah [Proyek Perangkat Lunak]"
255
+ if (-not $in_course) { $in_course = "Proyek Perangkat Lunak" }
256
+
257
+ $in_lecturer = Read-Host "Dosen Pengampu [Dr. Nama Dosen, M.Kom.]"
258
+ if (-not $in_lecturer) { $in_lecturer = "Dr. Nama Dosen, M.Kom." }
259
+
260
+ $in_author = Read-Host "Nama Penulis 1 [Nama Mahasiswa]"
261
+ if (-not $in_author) { $in_author = "Nama Mahasiswa" }
262
+
263
+ $in_nim = Read-Host "NIM Penulis 1 [12345678]"
264
+ if (-not $in_nim) { $in_nim = "12345678" }
265
+
266
+ $in_institution = Read-Host "Institusi/Universitas [UNIVERSITAS TEKNOLOGI]"
267
+ if (-not $in_institution) { $in_institution = "UNIVERSITAS TEKNOLOGI" }
268
+
269
+ $in_faculty = Read-Host "Fakultas [FAKULTAS ILMU KOMPUTER]"
270
+ if (-not $in_faculty) { $in_faculty = "FAKULTAS ILMU KOMPUTER" }
271
+
272
+ $in_year = Read-Host "Tahun Akademik [2026/2027]"
273
+ if (-not $in_year) { $in_year = "2026/2027" }
274
+
275
+ Write-Host ""
276
+ Write-Host "Pilihan Preset Format Kampus:" -ForegroundColor Blue
277
+ Write-Host " standard / skripsi-4433 / ui-skripsi / itb-ta / ugm-skripsi / its-skripsi / unpad-skripsi"
278
+ $in_preset = Read-Host "Preset Format [standard]"
279
+ if (-not $in_preset) { $in_preset = "standard" }
280
+
281
+ $curDate = (Get-Date -Format "MMMM yyyy")
282
+
283
+ $escTitle = Escape-Yaml $in_title
284
+ $escSubtitle = Escape-Yaml $in_subtitle
285
+ $escCourse = Escape-Yaml $in_course
286
+ $escLecturer = Escape-Yaml $in_lecturer
287
+ $escAuthor = Escape-Yaml $in_author
288
+ $escNim = Escape-Yaml $in_nim
289
+ $escInstitution = Escape-Yaml $in_institution
290
+ $escFaculty = Escape-Yaml $in_faculty
291
+ $escYear = Escape-Yaml $in_year
292
+ $escPreset = Escape-Yaml $in_preset
293
+
294
+ $yamlContent = @"
295
+ title: "$escTitle"
296
+ subtitle: "$escSubtitle"
297
+ course: "$escCourse"
298
+ lecturer: "$escLecturer"
299
+ author:
300
+ - name: "$escAuthor"
301
+ nim: "$escNim"
302
+ institution: "$escInstitution"
303
+ faculty: "$escFaculty"
304
+ year: "$escYear"
305
+ date: "$curDate"
306
+ preset: "$escPreset"
307
+ "@
308
+
309
+ Set-Content -Path "metadata.yml" -Value $yamlContent
310
+ Write-Host ""
311
+ Write-Host "metadata.yml berhasil diperbarui!" -ForegroundColor Green
312
+ Write-Host "Jalankan '.\laporan.ps1 build' untuk mulai menghasilkan laporan." -ForegroundColor Cyan
313
+ }
314
+
315
+ function Cmd-Test {
316
+ Show-Banner
317
+ Write-Host "Menjalankan Test Suite..." -ForegroundColor Blue
318
+ $bashCmd = Get-Command "bash" -ErrorAction SilentlyContinue
319
+ if ($bashCmd) {
320
+ & bash test.sh
321
+ } else {
322
+ $pyCmd = if (Get-Command "python3" -ErrorAction SilentlyContinue) { "python3" } elseif (Get-Command "python" -ErrorAction SilentlyContinue) { "python" } else { "" }
323
+ if ($pyCmd) {
324
+ Write-Host "Menjalankan validasi skema preset..." -ForegroundColor Blue
325
+ & $pyCmd scripts/validate-preset.py --all
326
+ } else {
327
+ Write-Host "Test suite membutuhkan bash atau python3." -ForegroundColor Yellow
328
+ }
329
+ }
330
+ }
331
+
332
+ function Cmd-Preset {
333
+ param ($Sub, $P1, $P2)
334
+ $pyCmd = if (Get-Command "python3" -ErrorAction SilentlyContinue) { "python3" } elseif (Get-Command "python" -ErrorAction SilentlyContinue) { "python" } else { "" }
335
+
336
+ switch ($Sub) {
337
+ "list" {
338
+ Show-Banner
339
+ Write-Host "Daftar Preset Format Kampus Tersedia:" -ForegroundColor Blue
340
+ Write-Host ""
341
+ Get-ChildItem -Path "presets" -Filter "*.yml" | ForEach-Object {
342
+ $pid = $_.BaseName
343
+ $name = (Select-String -Path $_.FullName -Pattern "^\s*name:\s*`"?(.*?)`"?\s*$" | Select-Object -First 1).Matches.Groups[1].Value
344
+ $desc = (Select-String -Path $_.FullName -Pattern "^\s*description:\s*`"?(.*?)`"?\s*$" | Select-Object -First 1).Matches.Groups[1].Value
345
+ Write-Host " * $pid - $name" -ForegroundColor Green
346
+ if ($desc) { Write-Host " $desc" -ForegroundColor Gray }
347
+ Write-Host ""
348
+ }
349
+ }
350
+ "show" {
351
+ if (-not $P1) { Write-Host "Error: Sebutkan ID preset. Contoh: .\laporan.ps1 preset show itb-ta" -ForegroundColor Red; return }
352
+ $file = "presets\$P1.yml"
353
+ if (Test-Path $file) {
354
+ Show-Banner
355
+ Write-Host "Konfigurasi Preset: $P1" -ForegroundColor Cyan
356
+ Write-Host "--------------------------------------------------------"
357
+ Get-Content $file
358
+ Write-Host "--------------------------------------------------------"
359
+ } else {
360
+ Write-Host "Preset '$P1' tidak ditemukan." -ForegroundColor Red
361
+ }
362
+ }
363
+ "apply" {
364
+ if (-not $P1) { Write-Host "Error: Sebutkan ID preset. Contoh: .\laporan.ps1 preset apply itb-ta" -ForegroundColor Red; return }
365
+ $file = "presets\$P1.yml"
366
+ if (-not (Test-Path $file)) { Write-Host "Preset '$P1' tidak ditemukan." -ForegroundColor Red; return }
367
+ if (-not (Test-Path "metadata.yml")) { Write-Host "metadata.yml tidak ditemukan." -ForegroundColor Red; return }
368
+
369
+ $content = Get-Content "metadata.yml" -Raw
370
+ if ($content -match "preset\s*:") {
371
+ $content = $content -replace "preset\s*:.*", "preset: `"$P1`""
372
+ } else {
373
+ $content += "`npreset: `"$P1`""
374
+ }
375
+ Set-Content -Path "metadata.yml" -Value $content -NoNewline
376
+ Write-Host "[OK] Preset '$P1' berhasil diterapkan ke metadata.yml!" -ForegroundColor Green
377
+ }
378
+ "validate" {
379
+ if (-not $pyCmd) { Write-Host "Error: Python 3 tidak ditemukan." -ForegroundColor Red; return }
380
+ if ($P1) {
381
+ $tgt = $P1
382
+ if (Test-Path "presets\$tgt.yml") { $tgt = "presets\$tgt.yml" }
383
+ & $pyCmd scripts/validate-preset.py $tgt
384
+ } else {
385
+ & $pyCmd scripts/validate-preset.py --all
386
+ }
387
+ }
388
+ "diff" {
389
+ if (-not $P1) { Write-Host "Error: Sebutkan setidaknya 1 preset untuk dibandingkan." -ForegroundColor Red; return }
390
+ $f1 = "presets\$P1.yml"
391
+ if (-not (Test-Path $f1)) { Write-Host "Preset '$P1' tidak ditemukan." -ForegroundColor Red; return }
392
+ if ($P2) {
393
+ $f2 = "presets\$P2.yml"
394
+ if (-not (Test-Path $f2)) { Write-Host "Preset '$P2' tidak ditemukan." -ForegroundColor Red; return }
395
+ Compare-Object (Get-Content $f1) (Get-Content $f2)
396
+ } else {
397
+ $curr = "standard"
398
+ if (Test-Path "metadata.yml") {
399
+ $content = Get-Content "metadata.yml" -Raw
400
+ if ($content -match "(?:preset|margin_preset)\s*:\s*[`"']?([a-zA-Z0-9_-]+)[`"']?") {
401
+ $curr = $matches[1]
402
+ }
403
+ }
404
+ $f2 = "presets\$curr.yml"
405
+ Compare-Object (Get-Content $f2) (Get-Content $f1)
406
+ }
407
+ }
408
+ "scan" {
409
+ if (-not $pyCmd) { Write-Host "Error: Python 3 tidak ditemukan." -ForegroundColor Red; return }
410
+ if (-not $P1) { Write-Host "Error: Masukkan path file PDF pedoman kampus." -ForegroundColor Red; return }
411
+ & $pyCmd scripts/scan-preset.py $P1 $P2
412
+ }
413
+ default {
414
+ Write-Host "Gunakan: .\laporan.ps1 preset [list | show <id> | apply <id> | validate | diff <id> | scan <file>]" -ForegroundColor Yellow
415
+ }
416
+ }
417
+ }
418
+
419
+ function Cmd-Clean {
420
+ Remove-Item -Force -ErrorAction SilentlyContinue Laporan.pdf, Laporan.docx, Laporan.html
421
+ Remove-Item -Recurse -Force -ErrorAction SilentlyContinue tmp, dist
422
+ Write-Host "[OK] Berkas output berhasil dibersihkan." -ForegroundColor Green
423
+ }
424
+
425
+ function Cmd-Stats {
426
+ $pyCmd = if (Get-Command "python3" -ErrorAction SilentlyContinue) { "python3" } elseif (Get-Command "python" -ErrorAction SilentlyContinue) { "python" } else { "" }
427
+ if ($pyCmd) {
428
+ & $pyCmd scripts/report-stats.py
429
+ } else {
430
+ Write-Host "Error: Python 3 tidak ditemukan." -ForegroundColor Red
431
+ }
432
+ }
433
+
434
+ function Cmd-Doctor {
435
+ $pyCmd = if (Get-Command "python3" -ErrorAction SilentlyContinue) { "python3" } elseif (Get-Command "python" -ErrorAction SilentlyContinue) { "python" } else { "" }
436
+ if ($pyCmd) {
437
+ & $pyCmd scripts/report-doctor.py
438
+ } else {
439
+ Write-Host "Error: Python 3 tidak ditemukan." -ForegroundColor Red
440
+ }
441
+ }
442
+
443
+ function Cmd-Bundle {
444
+ $pyCmd = if (Get-Command "python3" -ErrorAction SilentlyContinue) { "python3" } elseif (Get-Command "python" -ErrorAction SilentlyContinue) { "python" } else { "" }
445
+ if ($pyCmd) {
446
+ & $pyCmd scripts/bundle.py
447
+ } else {
448
+ Write-Host "Error: Python 3 tidak ditemukan." -ForegroundColor Red
449
+ }
450
+ }
451
+
452
+ function Cmd-View {
453
+ if (Test-Path "Laporan.pdf") {
454
+ Start-Process "Laporan.pdf"
455
+ } else {
456
+ Write-Host "Laporan.pdf belum dibuat. Jalankan '.\laporan.ps1 build' terlebih dahulu." -ForegroundColor Red
457
+ }
458
+ }
459
+
460
+ function Cmd-Watch {
461
+ Show-Banner
462
+ Write-Host "Memantau perubahan berkas dan auto-rebuild... (Tekan Ctrl+C untuk berhenti)" -ForegroundColor Cyan
463
+ $scriptPath = $MyInvocation.MyCommand.Definition
464
+ if (-not $scriptPath) { $scriptPath = $PSCommandPath }
465
+ if (-not $scriptPath) { $scriptPath = ".\laporan.ps1" }
466
+
467
+ $watcher = New-Object System.IO.FileSystemWatcher
468
+ $watcher.Path = (Get-Location).Path
469
+ $watcher.IncludeSubdirectories = $true
470
+ $watcher.EnableRaisingEvents = $true
471
+ $watcher.Filter = "*.*"
472
+
473
+ $action = {
474
+ $path = $Event.SourceEventArgs.FullPath
475
+ if ($path -notmatch '(\.pdf|\.docx|tmp|dist|\.git)' -and ($path -match '(\.md|\.typ|\.yml|\.bib)')) {
476
+ Write-Host "[Perubahan Terdeteksi] $path -> Membangun ulang..." -ForegroundColor Yellow
477
+ if (Get-Command Cmd-Build -ErrorAction SilentlyContinue) {
478
+ Cmd-Build
479
+ } elseif ($using:scriptPath -and (Test-Path $using:scriptPath)) {
480
+ & powershell -ExecutionPolicy Bypass -File $using:scriptPath build
481
+ } else {
482
+ powershell -ExecutionPolicy Bypass -File ".\laporan.ps1" build
483
+ }
484
+ }
485
+ }
486
+
487
+ Register-ObjectEvent $watcher "Changed" -Action $action | Out-Null
488
+ Register-ObjectEvent $watcher "Created" -Action $action | Out-Null
489
+
490
+ try {
491
+ while ($true) { Start-Sleep -Seconds 1 }
492
+ } finally {
493
+ Get-EventSubscriber | Unregister-Event
494
+ $watcher.Dispose()
495
+ }
496
+ }
497
+
498
+ switch ($Command.ToLower()) {
499
+ "build" { Cmd-Build }
500
+ "pdf" { Cmd-Build-PDF }
501
+ "docx" { Cmd-Build-DOCX }
502
+ "init" { Cmd-Init }
503
+ "stats" { Cmd-Stats }
504
+ "doctor" { Cmd-Doctor }
505
+ "bundle" { Cmd-Bundle }
506
+ "setup" { & powershell -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot "scripts\setup-deps.ps1") }
507
+ "sync-skills" {
508
+ if (Get-Command "node" -ErrorAction SilentlyContinue) {
509
+ node (Join-Path $PSScriptRoot "bin\laporan-generator.js") sync-hosts
510
+ } else {
511
+ Write-Host "Node.js diperlukan untuk sinkronisasi multi-host AI agent." -ForegroundColor Yellow
512
+ }
513
+ }
514
+ "sync-hosts" {
515
+ if (Get-Command "node" -ErrorAction SilentlyContinue) {
516
+ node (Join-Path $PSScriptRoot "bin\laporan-generator.js") sync-hosts
517
+ } else {
518
+ Write-Host "Node.js diperlukan untuk sinkronisasi multi-host AI agent." -ForegroundColor Yellow
519
+ }
520
+ }
521
+ "check" { Cmd-Check }
522
+ "clean" { Cmd-Clean }
523
+ "view" { Cmd-View }
524
+ "watch" { Cmd-Watch }
525
+ "test" { Cmd-Test }
526
+ "preset" { Cmd-Preset $SubCommand $Arg1 $Arg2 }
527
+ "help" { Show-Help }
528
+ default { Show-Help }
529
+ }