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,447 @@
1
+ #!/usr/bin/env bash
2
+ # ==============================================================================
3
+ # Laporan Generator CLI Helper (./laporan)
4
+ # ==============================================================================
5
+ set -e
6
+
7
+ GREEN='\033[0;32m'
8
+ BLUE='\033[0;34m'
9
+ CYAN='\033[0;36m'
10
+ YELLOW='\033[1;33m'
11
+ RED='\033[0;31m'
12
+ BOLD='\033[1m'
13
+ NC='\033[0m'
14
+
15
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
16
+ cd "$SCRIPT_DIR"
17
+
18
+ show_banner() {
19
+ echo -e "${CYAN}${BOLD}"
20
+ echo " ========================================================"
21
+ echo " LAPORAN GENERATOR CLI v2.6.0 "
22
+ echo " Otomatisasi Dokumen Akademik (Typst + DOCX Engine) "
23
+ echo " ========================================================"
24
+ echo -e "${NC}"
25
+ }
26
+
27
+ show_help() {
28
+ show_banner
29
+ echo -e "${BOLD}Penggunaan:${NC} ./laporan <perintah>"
30
+ echo ""
31
+ echo -e "${BOLD}Perintah yang Tersedia:${NC}"
32
+ echo -e " ${GREEN}build${NC} Kompilasi PDF dan DOCX sekaligus"
33
+ echo -e " ${GREEN}pdf${NC} Kompilasi dokumen PDF (via Typst)"
34
+ echo -e " ${GREEN}docx${NC} Kompilasi dokumen Microsoft Word (.docx)"
35
+ echo -e " ${GREEN}init${NC} Wizard interaktif untuk konfigurasi awal metadata"
36
+ echo -e " ${GREEN}preset${NC} Kelola preset format kampus (list/show/apply/diff/validate)"
37
+ echo -e " ${GREEN}stats${NC} Analisis statistik kata, halaman, gambar, dan durasi baca"
38
+ echo -e " ${GREEN}doctor${NC} Audit kesehatan proyek (broken images, sitasi hilang, dll.)"
39
+ echo -e " ${GREEN}bundle${NC} Kemas seluruh laporan (PDF, DOCX, MD) menjadi arsip zip"
40
+ echo -e " ${GREEN}setup${NC} Pasang dependensi sistem otomatis (Linux, macOS, Nix, Docker)"
41
+ echo -e " ${GREEN}sync-skills${NC} Sinkronkan skill AI agent ke Antigravity, Claude, Gemini, Grok"
42
+ echo -e " ${GREEN}check${NC} Audit dependensi sistem dan struktur proyek"
43
+ echo -e " ${GREEN}test${NC} Jalankan suite pengujian otomatis (test.sh)"
44
+ echo -e " ${GREEN}view${NC} Buka dokumen Laporan.pdf di viewer"
45
+ echo -e " ${GREEN}watch${NC} Pantau perubahan berkas dan auto-rebuild (live)"
46
+ echo -e " ${GREEN}clean${NC} Bersihkan berkas output dan direktori sementara"
47
+ echo -e " ${GREEN}help${NC} Tampilkan panduan bantuan ini"
48
+ echo ""
49
+ echo -e "${YELLOW}Contoh:${NC}"
50
+ echo -e " ./laporan build"
51
+ echo -e " ./laporan preset list"
52
+ echo -e " ./laporan preset apply itb-ta"
53
+ }
54
+
55
+ cmd_check() {
56
+ show_banner
57
+ echo -e "${BLUE}${BOLD}[1/2] Memeriksa Dependensi Sistem...${NC}"
58
+
59
+ local all_ok=true
60
+
61
+ check_dep() {
62
+ local name="$1"
63
+ local cmd="$2"
64
+ local req="$3"
65
+ if command -v "$cmd" &>/dev/null; then
66
+ echo -e " [${GREEN}OK${NC}] $name ($cmd) terpasang: $(command -v "$cmd")"
67
+ else
68
+ if [ "$req" = "required" ]; then
69
+ echo -e " [${RED}FAIL${NC}] $name ($cmd) ${RED}TIDAK DITEMUKAN${NC} (Wajib)"
70
+ all_ok=false
71
+ else
72
+ echo -e " [${YELLOW}INFO${NC}] $name ($cmd) tidak ditemukan (Opsional, untuk auto-inject nomor halaman Word)"
73
+ fi
74
+ fi
75
+ }
76
+
77
+ check_dep "Pandoc" "pandoc" "required"
78
+ check_dep "Typst" "typst" "required"
79
+ check_dep "ImageMagick" "magick" "required" 2>/dev/null || check_dep "ImageMagick" "convert" "required"
80
+ check_dep "Python 3" "python3" "required"
81
+ check_dep "LibreOffice" "soffice" "optional"
82
+
83
+ echo ""
84
+ echo -e "${BLUE}${BOLD}[2/2] Memeriksa Berkas Proyek...${NC}"
85
+
86
+ check_file() {
87
+ local file="$1"
88
+ local desc="$2"
89
+ if [ -f "$file" ]; then
90
+ echo -e " [${GREEN}OK${NC}] $desc ($file)"
91
+ else
92
+ echo -e " [${RED}FAIL${NC}] $desc ($file) tidak ditemukan"
93
+ all_ok=false
94
+ fi
95
+ }
96
+
97
+ check_dir() {
98
+ local dir="$1"
99
+ local desc="$2"
100
+ if [ -d "$dir" ]; then
101
+ echo -e " [${GREEN}OK${NC}] $desc ($dir)"
102
+ else
103
+ echo -e " [${RED}FAIL${NC}] $desc ($dir) tidak ditemukan"
104
+ all_ok=false
105
+ fi
106
+ }
107
+
108
+ check_file "metadata.yml" "Metadata laporan"
109
+ check_file "cover.md" "Kata pengantar & outline"
110
+ check_file "template.typ" "Template Typst"
111
+ check_file "reference.docx" "Template Word"
112
+ check_file "references.bib" "Daftar pustaka"
113
+ check_dir "presets" "Direktori preset kampus"
114
+ check_dir "chapters" "Direktori bab laporan"
115
+
116
+ echo ""
117
+ if [ "$all_ok" = true ]; then
118
+ echo -e "${GREEN}${BOLD}Semua dependensi dan berkas proyek lengkap dan siap digunakan!${NC}"
119
+ else
120
+ echo -e "${RED}${BOLD}Ada beberapa komponen yang kurang. Silakan lengkapi sebelum build.${NC}"
121
+ echo -e "${YELLOW}Tips: Gunakan 'nix develop' atau Docker untuk instalasi instan.${NC}"
122
+ fi
123
+ }
124
+
125
+ cmd_preset() {
126
+ local subcmd="${1:-list}"
127
+ case "$subcmd" in
128
+ list)
129
+ show_banner
130
+ echo -e "${BLUE}${BOLD}Daftar Preset Format Kampus Tersedia:${NC}"
131
+ echo ""
132
+ if [ -d presets ]; then
133
+ for p in presets/*.yml; do
134
+ if [ -f "$p" ]; then
135
+ local pid
136
+ pid=$(basename "$p" .yml)
137
+ local pname
138
+ pname=$(grep -E '^[[:space:]]*name:' "$p" 2>/dev/null | head -n 1 | cut -d: -f2- | tr -d '"\r\n' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
139
+ local pdesc
140
+ pdesc=$(grep -E '^[[:space:]]*description:' "$p" 2>/dev/null | head -n 1 | cut -d: -f2- | tr -d '"\r\n' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
141
+ echo -e " * ${GREEN}${BOLD}$pid${NC} - ${BOLD}${pname:-$pid}${NC}"
142
+ if [ -n "$pdesc" ]; then
143
+ echo -e " ${pdesc}"
144
+ fi
145
+ echo ""
146
+ fi
147
+ done
148
+ else
149
+ echo -e "${RED}Direktori presets/ tidak ditemukan.${NC}"
150
+ fi
151
+ echo -e "${YELLOW}Perintah Terkait:${NC}"
152
+ echo -e " Pindai pedoman PDF : ${CYAN}./laporan preset scan <pedoman.pdf>${NC}"
153
+ echo -e " Lihat detail preset: ${CYAN}./laporan preset show <preset-id>${NC}"
154
+ echo -e " Bandingkan preset : ${CYAN}./laporan preset diff <preset-1> [preset-2]${NC}"
155
+ echo -e " Validasi preset : ${CYAN}./laporan preset validate [preset-id]${NC}"
156
+ echo -e " Terapkan preset : ${CYAN}./laporan preset apply <preset-id>${NC}"
157
+ ;;
158
+ scan)
159
+ local pdf_file="$2"
160
+ if [ -z "$pdf_file" ]; then
161
+ echo -e "${RED}Error: Masukkan path file PDF pedoman kampus.${NC}"
162
+ echo "Contoh: ./laporan preset scan /path/ke/pedoman.pdf"
163
+ exit 1
164
+ fi
165
+ if [ ! -f "$pdf_file" ]; then
166
+ echo -e "${RED}Error: Berkas '$pdf_file' tidak ditemukan.${NC}"
167
+ exit 1
168
+ fi
169
+ shift
170
+ python3 scripts/scan-preset.py "$@"
171
+ ;;
172
+ validate)
173
+ shift
174
+ if [ -n "$1" ]; then
175
+ local t="$1"
176
+ [ -f "presets/${t}.yml" ] && t="presets/${t}.yml"
177
+ python3 scripts/validate-preset.py "$t"
178
+ else
179
+ python3 scripts/validate-preset.py --all
180
+ fi
181
+ ;;
182
+ diff)
183
+ local p1="$2"
184
+ local p2="$3"
185
+ if [ -z "$p1" ]; then
186
+ echo -e "${RED}Error: Sebutkan setidaknya 1 preset untuk dibandingkan.${NC}"
187
+ echo "Contoh: ./laporan preset diff itb-ta ui-skripsi"
188
+ exit 1
189
+ fi
190
+ if [ ! -f "presets/${p1}.yml" ]; then
191
+ echo -e "${RED}Preset '${p1}' tidak ditemukan di folder presets/${NC}"
192
+ exit 1
193
+ fi
194
+ show_banner
195
+ if [ -n "$p2" ]; then
196
+ if [ ! -f "presets/${p2}.yml" ]; then
197
+ echo -e "${RED}Preset '${p2}' tidak ditemukan di folder presets/${NC}"
198
+ exit 1
199
+ fi
200
+ echo -e "${CYAN}${BOLD}Perbandingan Preset: ${p1} VS ${p2}${NC}"
201
+ echo "========================================================"
202
+ diff -u "presets/${p1}.yml" "presets/${p2}.yml" || true
203
+ else
204
+ local curr
205
+ curr=$(grep -E '^[[:space:]]*(preset|margin_preset):' metadata.yml 2>/dev/null | head -n 1 | cut -d: -f2- | tr -d '\"'\''\r\n ')
206
+ curr=${curr:-"standard"}
207
+ echo -e "${CYAN}${BOLD}Perbandingan: Aktif (${curr}) VS Target (${p1})${NC}"
208
+ echo "========================================================"
209
+ diff -u "presets/${curr}.yml" "presets/${p1}.yml" 2>/dev/null || true
210
+ fi
211
+ echo "========================================================"
212
+ ;;
213
+ show)
214
+ local target="$2"
215
+ if [ -z "$target" ]; then
216
+ echo -e "${RED}Error: Sebutkan ID preset. Contoh: ./laporan preset show itb-ta${NC}"
217
+ exit 1
218
+ fi
219
+ if [ -f "presets/${target}.yml" ]; then
220
+ show_banner
221
+ echo -e "${CYAN}${BOLD}Konfigurasi Preset: ${target}${NC}"
222
+ echo "--------------------------------------------------------"
223
+ cat "presets/${target}.yml"
224
+ echo "--------------------------------------------------------"
225
+ else
226
+ echo -e "${RED}Preset '${target}' tidak ditemukan di folder presets/${NC}"
227
+ exit 1
228
+ fi
229
+ ;;
230
+ apply)
231
+ local target="$2"
232
+ if [ -z "$target" ]; then
233
+ echo -e "${RED}Error: Sebutkan ID preset. Contoh: ./laporan preset apply itb-ta${NC}"
234
+ exit 1
235
+ fi
236
+ if [ ! -f "presets/${target}.yml" ]; then
237
+ echo -e "${RED}Preset '${target}' tidak ditemukan di presets/${NC}"
238
+ exit 1
239
+ fi
240
+ if [ ! -f "metadata.yml" ]; then
241
+ echo -e "${RED}metadata.yml tidak ditemukan. Jalankan './laporan init' terlebih dahulu.${NC}"
242
+ exit 1
243
+ fi
244
+ if grep -qE '^\s*preset:' metadata.yml; then
245
+ sed -i.bak -E "s/^\s*preset:.*/preset: \"$target\"/" metadata.yml && rm -f metadata.yml.bak
246
+ elif grep -qE '^\s*margin_preset:' metadata.yml; then
247
+ sed -i.bak -E "s/^\s*margin_preset:.*/preset: \"$target\"/" metadata.yml && rm -f metadata.yml.bak
248
+ elif grep -q '^\.\.\.' metadata.yml; then
249
+ sed -i.bak -E "s/^\.\.\./preset: \"$target\"\n.../" metadata.yml && rm -f metadata.yml.bak
250
+ else
251
+ echo "preset: \"$target\"" >> metadata.yml
252
+ fi
253
+ echo -e "${GREEN}${BOLD}[OK] Preset '${target}' berhasil diterapkan ke metadata.yml!${NC}"
254
+ ;;
255
+ *)
256
+ echo -e "${RED}Sub-perintah preset tidak dikenal: $subcmd${NC}"
257
+ echo "Gunakan: ./laporan preset [list | scan <file> | show <id> | diff <id> | validate | apply <id>]"
258
+ exit 1
259
+ ;;
260
+ esac
261
+ }
262
+
263
+ yaml_escape() {
264
+ local val="$1"
265
+ val="${val//\\/\\\\}"
266
+ val="${val//\"/\\\"}"
267
+ val="${val//$'\r'/}"
268
+ val="${val//$'\n'/ }"
269
+ echo -n "$val"
270
+ }
271
+
272
+ cmd_init() {
273
+ show_banner
274
+ echo -e "${CYAN}${BOLD}Wizard Konfigurasi Laporan Akademik${NC}"
275
+ echo "Isi data di bawah ini (tekan Enter untuk memakai nilai default):"
276
+ echo ""
277
+
278
+ read -rp "Judul Laporan [LAPORAN PROYEK AKADEMIK]: " in_title
279
+ in_title=${in_title:-"LAPORAN PROYEK AKADEMIK"}
280
+
281
+ read -rp "Subjudul [DOKUMENTASI DAN ANALISIS IMPLEMENTASI]: " in_subtitle
282
+ in_subtitle=${in_subtitle:-"DOKUMENTASI DAN ANALISIS IMPLEMENTASI"}
283
+
284
+ read -rp "Mata Kuliah [Proyek Perangkat Lunak]: " in_course
285
+ in_course=${in_course:-"Proyek Perangkat Lunak"}
286
+
287
+ read -rp "Dosen Pengampu [Dr. Nama Dosen, M.Kom.]: " in_lecturer
288
+ in_lecturer=${in_lecturer:-"Dr. Nama Dosen, M.Kom."}
289
+
290
+ read -rp "Nama Penulis 1 [Nama Mahasiswa]: " in_author
291
+ in_author=${in_author:-"Nama Mahasiswa"}
292
+
293
+ read -rp "NIM Penulis 1 [12345678]: " in_nim
294
+ in_nim=${in_nim:-"12345678"}
295
+
296
+ read -rp "Institusi/Universitas [UNIVERSITAS TEKNOLOGI]: " in_institution
297
+ in_institution=${in_institution:-"UNIVERSITAS TEKNOLOGI"}
298
+
299
+ read -rp "Fakultas [FAKULTAS ILMU KOMPUTER]: " in_faculty
300
+ in_faculty=${in_faculty:-"FAKULTAS ILMU KOMPUTER"}
301
+
302
+ read -rp "Tahun Akademik [2026/2027]: " in_year
303
+ in_year=${in_year:-"2026/2027"}
304
+
305
+ echo ""
306
+ echo -e "${BLUE}Pilihan Preset Format Kampus:${NC}"
307
+ echo " standard / skripsi-4433 / ui-skripsi / itb-ta / ugm-skripsi / its-skripsi"
308
+ read -rp "Preset Format [standard]: " in_preset
309
+ in_preset=${in_preset:-"standard"}
310
+
311
+ cat << YAML_EOF > metadata.yml
312
+ title: "$(yaml_escape "$in_title")"
313
+ subtitle: "$(yaml_escape "$in_subtitle")"
314
+ course: "$(yaml_escape "$in_course")"
315
+ lecturer: "$(yaml_escape "$in_lecturer")"
316
+ author:
317
+ - name: "$(yaml_escape "$in_author")"
318
+ nim: "$(yaml_escape "$in_nim")"
319
+ institution: "$(yaml_escape "$in_institution")"
320
+ faculty: "$(yaml_escape "$in_faculty")"
321
+ year: "$(yaml_escape "$in_year")"
322
+ date: "$(date +'%B %Y')"
323
+ preset: "$(yaml_escape "$in_preset")"
324
+ YAML_EOF
325
+
326
+ echo ""
327
+ echo -e "${GREEN}${BOLD}metadata.yml berhasil diperbarui!${NC}"
328
+ echo -e "Jalankan ${CYAN}./laporan build${NC} untuk mulai menghasilkan laporan."
329
+ }
330
+
331
+ cmd_build() {
332
+ show_banner
333
+ echo -e "${BLUE}${BOLD}1. Membangun Dokumen PDF (Typst Engine)...${NC}"
334
+ ./build.sh
335
+ echo ""
336
+ echo -e "${BLUE}${BOLD}2. Membangun Dokumen Microsoft Word (DOCX Multi-Pass)...${NC}"
337
+ make docx
338
+ echo ""
339
+ echo -e "${GREEN}${BOLD}Dokumen PDF dan DOCX berhasil dibuat!${NC}"
340
+ echo -e " - ${CYAN}Laporan.pdf${NC}"
341
+ echo -e " - ${CYAN}Laporan.docx${NC}"
342
+ }
343
+
344
+ cmd_pdf() {
345
+ show_banner
346
+ echo -e "${BLUE}${BOLD}Membangun Dokumen PDF...${NC}"
347
+ ./build.sh
348
+ }
349
+
350
+ cmd_docx() {
351
+ show_banner
352
+ echo -e "${BLUE}${BOLD}Membangun Dokumen DOCX...${NC}"
353
+ make docx
354
+ }
355
+
356
+ cmd_test() {
357
+ show_banner
358
+ echo -e "${BLUE}${BOLD}Menjalankan Test Suite...${NC}"
359
+ ./test.sh
360
+ }
361
+
362
+ cmd_view() {
363
+ make view
364
+ }
365
+
366
+ cmd_clean() {
367
+ make clean
368
+ echo -e "${GREEN}Berkas temporary berhasil dibersihkan.${NC}"
369
+ }
370
+
371
+ cmd_watch() {
372
+ make watch
373
+ }
374
+
375
+ cmd_stats() {
376
+ python3 scripts/report-stats.py
377
+ }
378
+
379
+ cmd_doctor() {
380
+ python3 scripts/report-doctor.py
381
+ }
382
+
383
+ cmd_bundle() {
384
+ python3 scripts/bundle.py
385
+ }
386
+
387
+ # Main routing
388
+ case "${1:-help}" in
389
+ build)
390
+ cmd_build
391
+ ;;
392
+ pdf)
393
+ cmd_pdf
394
+ ;;
395
+ docx)
396
+ cmd_docx
397
+ ;;
398
+ init)
399
+ cmd_init
400
+ ;;
401
+ preset)
402
+ shift
403
+ cmd_preset "$@"
404
+ ;;
405
+ stats)
406
+ cmd_stats
407
+ ;;
408
+ doctor)
409
+ cmd_doctor
410
+ ;;
411
+ bundle)
412
+ cmd_bundle
413
+ ;;
414
+ setup)
415
+ bash scripts/setup-deps.sh
416
+ ;;
417
+ sync-skills|sync-hosts)
418
+ if command -v node >/dev/null 2>&1; then
419
+ node bin/laporan-generator.js sync-hosts
420
+ else
421
+ echo "Node.js diperlukan untuk sinkronisasi multi-host AI agent."
422
+ fi
423
+ ;;
424
+ check)
425
+ cmd_check
426
+ ;;
427
+ test)
428
+ cmd_test
429
+ ;;
430
+ view)
431
+ cmd_view
432
+ ;;
433
+ clean)
434
+ cmd_clean
435
+ ;;
436
+ watch)
437
+ cmd_watch
438
+ ;;
439
+ help|--help|-h)
440
+ show_help
441
+ ;;
442
+ *)
443
+ echo -e "${RED}Perintah tidak dikenal: $1${NC}"
444
+ echo "Gunakan './laporan help' untuk melihat daftar perintah."
445
+ exit 1
446
+ ;;
447
+ esac