diary-docs 0.1.0__py3-none-any.whl
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.
- diary/__init__.py +1 -0
- diary/__main__.py +3 -0
- diary/aimb/__init__.py +48 -0
- diary/aimb/hasher.py +157 -0
- diary/aimb/merge.py +252 -0
- diary/aimb/parser.py +202 -0
- diary/cli.py +999 -0
- diary/git_utils.py +202 -0
- diary/indexer/__init__.py +44 -0
- diary/indexer/database.py +340 -0
- diary/indexer/extractors.py +468 -0
- diary/indexer/gitignore.py +62 -0
- diary/indexer/indexer.py +511 -0
- diary/indexer/reporter.py +137 -0
- diary/indexer/scanner.py +65 -0
- diary/sync/__init__.py +33 -0
- diary/sync/detector.py +405 -0
- diary/sync/engine.py +404 -0
- diary/sync/protocol.py +176 -0
- diary/templates.py +102 -0
- diary_docs-0.1.0.dist-info/METADATA +228 -0
- diary_docs-0.1.0.dist-info/RECORD +26 -0
- diary_docs-0.1.0.dist-info/WHEEL +5 -0
- diary_docs-0.1.0.dist-info/entry_points.txt +2 -0
- diary_docs-0.1.0.dist-info/licenses/LICENSE +21 -0
- diary_docs-0.1.0.dist-info/top_level.txt +1 -0
diary/cli.py
ADDED
|
@@ -0,0 +1,999 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import os
|
|
3
|
+
import re
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from rich.console import Console
|
|
8
|
+
from rich.text import Text
|
|
9
|
+
from InquirerPy import inquirer
|
|
10
|
+
|
|
11
|
+
from diary.indexer.indexer import run_index
|
|
12
|
+
from diary.indexer.reporter import generate_report
|
|
13
|
+
from diary.sync.engine import run_sync, SyncConfig
|
|
14
|
+
from diary.sync.protocol import serialize_report
|
|
15
|
+
from diary.templates import CATALOG_TEMPLATE, MKDOCS_TEMPLATE, aimb_wrap_body
|
|
16
|
+
|
|
17
|
+
console = Console()
|
|
18
|
+
|
|
19
|
+
BANNER = r"""
|
|
20
|
+
╔════════════════════════════════════════╗
|
|
21
|
+
║ ║
|
|
22
|
+
║ ██████╗ ██╗ █████╗ ██████╗ ██╗ ██╗ ║
|
|
23
|
+
║ ██╔══██╗██║██╔══██╗██╔══██╗╚██╗ ██╔╝ ║
|
|
24
|
+
║ ██║ ██║██║███████║██████╔╝ ╚████╔╝ ║
|
|
25
|
+
║ ██║ ██║██║██╔══██║██╔══██╗ ╚██╔╝ ║
|
|
26
|
+
║ ██████╔╝██║██║ ██║██║ ██║ ██║ ║
|
|
27
|
+
║ ╚═════╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ║
|
|
28
|
+
║ ║
|
|
29
|
+
╚════════════════════════════════════════╝
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
SYNC_CONTENT = """\
|
|
34
|
+
---
|
|
35
|
+
description: Synchronize documentation AIMB blocks with detected code changes using the DIARY sync protocol
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
# /diary-sync
|
|
39
|
+
|
|
40
|
+
Sinkronisasi dokumentasi dengan perubahan kode yang terdeteksi. Agent ini membaca output dari `diary sync --dry-run`, memproses perubahan satu per satu, dan menulis ulang konten AIMB block yang kedaluwarsa.
|
|
41
|
+
|
|
42
|
+
## Prerequisites
|
|
43
|
+
|
|
44
|
+
- `diary sync` CLI command harus sudah terinstall
|
|
45
|
+
- Workspace harus dalam keadaan **clean git state** (no uncommitted changes selain yang dimaksud)
|
|
46
|
+
- Dokumentasi harus sudah memiliki struktur AIMB blocks
|
|
47
|
+
- **Semua perubahan kode harus sudah di-commit ke git** — diary sync membandingkan file saat ini dengan git history untuk mendeteksi perubahan. File yang untracked (`??` di git status) tidak akan terdeteksi sebagai perubahan. Commit dulu sebelum menjalankan sync.
|
|
48
|
+
|
|
49
|
+
## SyncReport JSON Protocol
|
|
50
|
+
|
|
51
|
+
Perintah `diary sync --dry-run` menghasilkan JSON dengan skema berikut:
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"branch": "feature/my-branch",
|
|
56
|
+
"timestamp": "2026-06-26T10:30:00+07:00",
|
|
57
|
+
"changes": [
|
|
58
|
+
{
|
|
59
|
+
"file_path": "src/services/auth.py",
|
|
60
|
+
"change_type": "modified",
|
|
61
|
+
"affected_docs": ["docs/techdocs/architecture.md"],
|
|
62
|
+
"confidence": 0.95
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
"conflicts": [
|
|
66
|
+
{
|
|
67
|
+
"file_path": "docs/techdocs/architecture.md",
|
|
68
|
+
"block_id": "arch-auth-flow",
|
|
69
|
+
"old_hash": "abc123def456",
|
|
70
|
+
"current_hash": "789ghi012jkl",
|
|
71
|
+
"diff_preview": "@@ -10,6 +10,8 @@\\n ..."
|
|
72
|
+
}
|
|
73
|
+
],
|
|
74
|
+
"stats": {
|
|
75
|
+
"files_scanned": 42,
|
|
76
|
+
"docs_updated": 0,
|
|
77
|
+
"conflicts": 1,
|
|
78
|
+
"duration_ms": 1523
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Field Reference
|
|
84
|
+
|
|
85
|
+
| Field | Type | Description |
|
|
86
|
+
|-------|------|-------------|
|
|
87
|
+
| `branch` | string | Nama branch saat ini |
|
|
88
|
+
| `timestamp` | string | ISO-8601 timestamp kapan sync dijalankan |
|
|
89
|
+
| `changes[]` | array | Daftar perubahan kode yang terdeteksi |
|
|
90
|
+
| `changes[].file_path` | string | Path file yang berubah (relative ke workspace) |
|
|
91
|
+
| `changes[].change_type` | string | `"modified"`, `"added"`, atau `"deleted"` |
|
|
92
|
+
| `changes[].affected_docs` | array | Path dokumentasi yang terpengaruh |
|
|
93
|
+
| `changes[].confidence` | float | 0.0 – 1.0, seberapa yakin detektor |
|
|
94
|
+
| `conflicts[]` | array | Daftar konflik AIMB block |
|
|
95
|
+
| `conflicts[].file_path` | string | File dokumentasi yang konflik |
|
|
96
|
+
| `conflicts[].block_id` | string | ID AIMB block yang bermasalah |
|
|
97
|
+
| `conflicts[].old_hash` | string | Hash tersimpan terakhir |
|
|
98
|
+
| `conflicts[].current_hash` | string | Hash saat ini di file |
|
|
99
|
+
| `conflicts[].diff_preview` | string | Unified diff antara old dan current |
|
|
100
|
+
| `stats.files_scanned` | int | Total file yang di-scan |
|
|
101
|
+
| `stats.docs_updated` | int | Dokumentasi yang sudah di-update (0 saat dry-run) |
|
|
102
|
+
| `stats.conflicts` | int | Jumlah konflik |
|
|
103
|
+
| `stats.duration_ms` | int | Durasi scan dalam milidetik |
|
|
104
|
+
|
|
105
|
+
## AIMB Blocks vs Manual Blocks
|
|
106
|
+
|
|
107
|
+
### AIMB Block (AI-Managed Block)
|
|
108
|
+
|
|
109
|
+
DIARY markdown files mungkin memiliki blok yang dikelola secara otomatis:
|
|
110
|
+
|
|
111
|
+
```html
|
|
112
|
+
<!-- ai-managed id="arch-overview" hash="a1b2c3d4" updated="2026-06-01" -->
|
|
113
|
+
Ini adalah konten yang dihasilkan oleh AI agent.
|
|
114
|
+
Setiap kali ada perubahan kode yang relevan, konten ini akan diperbarui.
|
|
115
|
+
<!-- /ai-managed -->
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Ciri-ciri:
|
|
119
|
+
- Diawali dengan `<!-- ai-managed id="..." hash="..." updated="..." -->`
|
|
120
|
+
- Diakhiri dengan `<!-- /ai-managed -->`
|
|
121
|
+
- **Hash** adalah SHA-256 dari konten block. Digunakan untuk deteksi konflik.
|
|
122
|
+
- **updated** adalah tanggal terakhir block ini diubah.
|
|
123
|
+
- Agent BOLEH mengubah konten block ini.
|
|
124
|
+
|
|
125
|
+
### Manual Block
|
|
126
|
+
|
|
127
|
+
```html
|
|
128
|
+
<!-- manual -->
|
|
129
|
+
Ini adalah konten yang ditulis manual oleh user.
|
|
130
|
+
Agent TIDAK BOLEH mengubah konten ini tanpa persetujuan eksplisit.
|
|
131
|
+
<!-- /manual -->
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Ciri-ciri:
|
|
135
|
+
- Diawali dengan `<!-- manual -->`
|
|
136
|
+
- Diakhiri dengan `<!-- /manual -->`
|
|
137
|
+
- Agent TIDAK BOLEH mengubah konten di dalamnya.
|
|
138
|
+
- Jika ada perubahan di luar AIMB block, itu dianggap manual edit.
|
|
139
|
+
|
|
140
|
+
### Non-Block Content
|
|
141
|
+
|
|
142
|
+
Konten markdown biasa (tanpa tag `<!-- ai-managed -->` atau `<!-- manual -->`) dianggap sebagai konten user yang tidak boleh disentuh oleh agent.
|
|
143
|
+
|
|
144
|
+
## Workflow
|
|
145
|
+
|
|
146
|
+
Agent WAJIB menjalankan langkah-langkah berikut secara berurutan:
|
|
147
|
+
|
|
148
|
+
### Step 1: Verify Git State & Dry-Run Analysis
|
|
149
|
+
|
|
150
|
+
**PENTING**: Sebelum menjalankan diary sync, pastikan semua perubahan kode sudah di-commit ke git.
|
|
151
|
+
|
|
152
|
+
Periksa status git terlebih dahulu:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
git status --short
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Jika ada file dengan status `??` (untracked) atau `M` (modified) yang merupakan bagian dari fitur baru, **commit terlebih dahulu**:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
git add <files>
|
|
162
|
+
git commit -m "feat: deskripsi perubahan"
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
File yang tidak di-commit **tidak akan terdeteksi** oleh diary sync karena tidak ada git history untuk dibandingkan.
|
|
166
|
+
|
|
167
|
+
Setelah git state clean, jalankan perintah berikut untuk mendapatkan analisis perubahan:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
python -m diary sync --dry-run
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Perintah ini mengembalikan JSON (SyncReport). Simpan output untuk referensi.
|
|
174
|
+
|
|
175
|
+
**Jika command tidak ditemukan**, hentikan dan beri tahu user bahwa `diary sync` belum terinstall.
|
|
176
|
+
|
|
177
|
+
### Step 2: Parse & Understand Change Scope
|
|
178
|
+
|
|
179
|
+
Parsing output JSON dan pahami scope perubahan:
|
|
180
|
+
|
|
181
|
+
1. **Periksa `conflicts[]`** — jika ada konflik, catat untuk step 4.
|
|
182
|
+
2. **Periksa `changes[]`** — setiap entry adalah file kode yang berubah.
|
|
183
|
+
3. **Perhatikan `confidence`**:
|
|
184
|
+
- `confidence >= 0.8`: perubahan jelas, aman diproses.
|
|
185
|
+
- `confidence < 0.8`: perubahan kurang jelas, tanya user sebelum memproses.
|
|
186
|
+
4. **Perhatikan `affected_docs`** — ini adalah file dokumentasi yang perlu diperbarui.
|
|
187
|
+
|
|
188
|
+
### Step 3: Process Each Change (High Confidence, No Conflict)
|
|
189
|
+
|
|
190
|
+
Untuk setiap perubahan dengan `confidence >= 0.8` dan tanpa konflik:
|
|
191
|
+
|
|
192
|
+
1. **Baca file dokumentasi yang terpengaruh** — gunakan path dari `affected_docs`.
|
|
193
|
+
2. **Baca file kode yang berubah** — pahami perubahan apa yang terjadi.
|
|
194
|
+
3. **Identifikasi AIMB block yang relevan** — cari `<!-- ai-managed id="..." ... -->` di file dokumentasi.
|
|
195
|
+
4. **Generate konten baru**:
|
|
196
|
+
- Analisis perubahan kode: apa yang berubah, fungsi baru, parameter baru, behavior baru.
|
|
197
|
+
- Gunakan kemampuan AI untuk menghasilkan konten dokumentasi profesional.
|
|
198
|
+
- Ikuti DIARY documentation style (formal, terstruktur, Bahasa Indonesia + English terms).
|
|
199
|
+
- Konten harus akurat mencerminkan state kode yang baru.
|
|
200
|
+
5. **Tulis konten baru** menggunakan fungsi `apply_replace()` logic dari merge module:
|
|
201
|
+
- Temukan AIMB block dengan ID yang sesuai.
|
|
202
|
+
- Ganti konten di antara open dan close tag.
|
|
203
|
+
- Hash dan tanggal akan diperbarui secara otomatis oleh `apply_replace()`.
|
|
204
|
+
|
|
205
|
+
Jika sebuah file dokumentasi memiliki beberapa AIMB block, hanya update block yang relevan dengan perubahan kode tersebut.
|
|
206
|
+
|
|
207
|
+
**PENTING**: Jangan mengubah konten di luar AIMB block. Jangan menyentuh manual blocks.
|
|
208
|
+
|
|
209
|
+
### Step 4: Handle Conflicts (DO NOT Auto-Resolve)
|
|
210
|
+
|
|
211
|
+
Jika ada `conflicts[]` di SyncReport:
|
|
212
|
+
|
|
213
|
+
1. **Print conflict summary** dalam format yang mudah dibaca:
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
⚠️ Merge Conflicts Detected
|
|
217
|
+
|
|
218
|
+
1. docs/techdocs/architecture.md — block "arch-auth-flow"
|
|
219
|
+
- Stored hash: abc123def456
|
|
220
|
+
- Current hash: 789ghi012jkl
|
|
221
|
+
- Status: Manual edit detected
|
|
222
|
+
|
|
223
|
+
Diff Preview:
|
|
224
|
+
```diff
|
|
225
|
+
@@ -10,6 +10,8 @@
|
|
226
|
+
...
|
|
227
|
+
```
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
2. **JANGAN auto-resolve**. Tanyakan ke user:
|
|
231
|
+
- "Apakah ingin menyimpan versi yang ada di file (manual edit) atau menimpa dengan konten baru?"
|
|
232
|
+
- Atau minta user untuk merge manual.
|
|
233
|
+
|
|
234
|
+
3. Jika user memutuskan, lakukan sesuai keputusan user. Jika user menyuruh timpa:
|
|
235
|
+
- Baca file dokumentasi.
|
|
236
|
+
- Gunakan `apply_replace()` untuk block yang konflik.
|
|
237
|
+
- Catat bahwa konflik di-resolve secara paksa.
|
|
238
|
+
|
|
239
|
+
### Step 5: Finalize Sync
|
|
240
|
+
|
|
241
|
+
Setelah semua perubahan ditulis, jalankan:
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
python -m diary sync --force
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Perintah ini akan:
|
|
248
|
+
- Menghitung ulang hash untuk semua AIMB block.
|
|
249
|
+
- Menyimpan hash baru ke database index.
|
|
250
|
+
- Menampilkan ringkasan final.
|
|
251
|
+
|
|
252
|
+
### Step 6: Report Summary
|
|
253
|
+
|
|
254
|
+
Buat ringkasan dalam format berikut:
|
|
255
|
+
|
|
256
|
+
```
|
|
257
|
+
✅ Diary Sync Completed
|
|
258
|
+
|
|
259
|
+
Files processed: 3
|
|
260
|
+
- src/services/auth.py → docs/techdocs/architecture.md (AIMB: arch-overview, arch-flow)
|
|
261
|
+
- src/models/user.py → docs/techdocs/api-contracts.md (AIMB: user-model)
|
|
262
|
+
- src/config/settings.py → docs/product/user-guide.md (AIMB: config-reference)
|
|
263
|
+
|
|
264
|
+
Conflicts: 1
|
|
265
|
+
- docs/techdocs/architecture.md — block "arch-auth-flow": ⚠️ Manual review needed
|
|
266
|
+
|
|
267
|
+
Stats:
|
|
268
|
+
- Total files scanned: 42
|
|
269
|
+
- Duration: 1523 ms
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Example: Full Session
|
|
273
|
+
|
|
274
|
+
Berikut contoh sesi lengkap:
|
|
275
|
+
|
|
276
|
+
### User Request
|
|
277
|
+
"Update dokumentasi setelah aku nambahin fitur rate limiting di middleware."
|
|
278
|
+
|
|
279
|
+
### Agent Execution
|
|
280
|
+
|
|
281
|
+
**Step 1 — Dry-Run:**
|
|
282
|
+
```bash
|
|
283
|
+
$ python -m diary sync --dry-run
|
|
284
|
+
|
|
285
|
+
{
|
|
286
|
+
"branch": "feature/rate-limit",
|
|
287
|
+
"timestamp": "2026-06-26T14:30:00+07:00",
|
|
288
|
+
"changes": [
|
|
289
|
+
{
|
|
290
|
+
"file_path": "src/middleware/ratelimit.py",
|
|
291
|
+
"change_type": "added",
|
|
292
|
+
"affected_docs": ["docs/techdocs/architecture.md"],
|
|
293
|
+
"confidence": 0.95
|
|
294
|
+
}
|
|
295
|
+
],
|
|
296
|
+
"conflicts": [],
|
|
297
|
+
"stats": { "files_scanned": 45, "docs_updated": 0, "conflicts": 0, "duration_ms": 1234 }
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**Step 2 — Parse:** Tidak ada konflik. Satu perubahan baru di middleware dengan confidence tinggi. File terdampak: `docs/techdocs/architecture.md`.
|
|
302
|
+
|
|
303
|
+
**Step 3 — Process:**
|
|
304
|
+
- Baca `docs/techdocs/architecture.md` → temukan AIMB block `id="arch-middleware"`.
|
|
305
|
+
- Baca `src/middleware/ratelimit.py` → pahami fitur rate limiting baru.
|
|
306
|
+
- Generate konten baru untuk block `arch-middleware` yang menjelaskan arsitektur rate limiting.
|
|
307
|
+
- Panggil `apply_replace()` untuk menulis konten baru.
|
|
308
|
+
|
|
309
|
+
**Step 4 — Skip** (tidak ada konflik).
|
|
310
|
+
|
|
311
|
+
**Step 5 — Finalize:**
|
|
312
|
+
```bash
|
|
313
|
+
python -m diary sync --force
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
**Step 6 — Report:**
|
|
317
|
+
```
|
|
318
|
+
✅ Diary Sync Completed
|
|
319
|
+
|
|
320
|
+
Files processed: 1
|
|
321
|
+
- src/middleware/ratelimit.py → docs/techdocs/architecture.md (AIMB: arch-middleware)
|
|
322
|
+
|
|
323
|
+
Conflicts: 0
|
|
324
|
+
|
|
325
|
+
Stats:
|
|
326
|
+
- Total files scanned: 45
|
|
327
|
+
- Duration: 891 ms
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
## Error Handling
|
|
331
|
+
|
|
332
|
+
| Scenario | Action |
|
|
333
|
+
|----------|--------|
|
|
334
|
+
| `diary sync --dry-run` gagal | Print error, minta user cek instalasi `diary` |
|
|
335
|
+
| Tidak ada perubahan | Laporkan "No changes detected. Documentation is up to date." |
|
|
336
|
+
| Semua perubahan low confidence | Tanya user apakah tetap diproses |
|
|
337
|
+
| Konflik + perubahan | Proses perubahan dulu, lalu tanya user soal konflik |
|
|
338
|
+
| `diary sync --force` gagal | Print stderr, minta user cek file lock atau write permission |
|
|
339
|
+
| File AIMB block tidak ditemukan | Cek apakah file masih ada. Jika sudah dihapus, skip. |
|
|
340
|
+
"""
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
SKILL_CONTENT = """\
|
|
344
|
+
---
|
|
345
|
+
description: Generate DIARY documentation content by analyzing the workspace codebase
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
# {heading}
|
|
349
|
+
|
|
350
|
+
Analyze the current workspace codebase and generate enterprise-grade documentation content for the DIARY structure.
|
|
351
|
+
|
|
352
|
+
## Target Audience
|
|
353
|
+
|
|
354
|
+
Documentation must be usable by:
|
|
355
|
+
- Business Analyst
|
|
356
|
+
- System Analyst
|
|
357
|
+
- Software Engineer
|
|
358
|
+
- QA Engineer
|
|
359
|
+
- DevOps Engineer
|
|
360
|
+
- Project Manager
|
|
361
|
+
- Stakeholder bisnis
|
|
362
|
+
|
|
363
|
+
## Documentation Style Guide
|
|
364
|
+
|
|
365
|
+
- Gunakan bahasa yang formal, jelas, dan profesional.
|
|
366
|
+
- Fokus pada kejelasan dibanding kompleksitas.
|
|
367
|
+
- Gunakan heading yang terstruktur.
|
|
368
|
+
- Gunakan tabel untuk informasi terstruktur.
|
|
369
|
+
- Berikan asumsi jika ada informasi yang tidak tersedia.
|
|
370
|
+
- Hindari penjelasan yang bertele-tele.
|
|
371
|
+
- Gunakan istilah yang konsisten di seluruh dokumen.
|
|
372
|
+
|
|
373
|
+
## Analysis Structure
|
|
374
|
+
|
|
375
|
+
Selalu analisis sistem dari sudut pandang:
|
|
376
|
+
|
|
377
|
+
1. **Business View** — Proses bisnis, flow, stakeholders
|
|
378
|
+
2. **Functional View** — Fitur, use case, requirement fungsional
|
|
379
|
+
3. **Application View** — Arsitektur aplikasi, komponen, module
|
|
380
|
+
4. **Integration View** — Integrasi dengan sistem eksternal, API
|
|
381
|
+
5. **Data View** — Model data, ERD, relasi
|
|
382
|
+
6. **Security View** — Autentikasi, otorisasi, keamanan data
|
|
383
|
+
7. **Deployment View** — Infrastruktur, CI/CD, environment
|
|
384
|
+
|
|
385
|
+
## Mermaid Diagram Rules
|
|
386
|
+
|
|
387
|
+
Diagram harus profesional dan mudah dibaca:
|
|
388
|
+
- Gunakan `flowchart TD` (Top-Down) sebagai default
|
|
389
|
+
- Hindari edge crossing
|
|
390
|
+
- Gunakan `subgraph` untuk grouping
|
|
391
|
+
- Maksimal 8-10 node per group
|
|
392
|
+
- Pisahkan layer dengan jelas menggunakan subgraph
|
|
393
|
+
- Jika diagram terlalu besar, pecah menjadi beberapa diagram
|
|
394
|
+
- Prioritaskan readability daripada kelengkapan
|
|
395
|
+
- Gunakan style yang konsisten: `style SubName fill:#4A90D9,color:#fff`
|
|
396
|
+
- Berikan label yang jelas pada setiap node dan edge
|
|
397
|
+
|
|
398
|
+
Contoh format diagram yang benar:
|
|
399
|
+
```mermaid
|
|
400
|
+
flowchart TD
|
|
401
|
+
subgraph "Presentation Layer"
|
|
402
|
+
UI[Web App]
|
|
403
|
+
end
|
|
404
|
+
subgraph "Application Layer"
|
|
405
|
+
API[API Gateway]
|
|
406
|
+
SVC[Service]
|
|
407
|
+
end
|
|
408
|
+
subgraph "Data Layer"
|
|
409
|
+
DB[(Database)]
|
|
410
|
+
end
|
|
411
|
+
UI --> API
|
|
412
|
+
API --> SVC
|
|
413
|
+
SVC --> DB
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
## Instructions
|
|
417
|
+
|
|
418
|
+
You are a documentation generator. Your task is to analyze the workspace codebase and produce
|
|
419
|
+
high-quality enterprise-grade documentation following DIARY guidelines.
|
|
420
|
+
|
|
421
|
+
IMPORTANT!!!
|
|
422
|
+
You MUST execute every step in order.
|
|
423
|
+
Do NOT skip any step.
|
|
424
|
+
|
|
425
|
+
### Step 1: Read Existing Docs Structure
|
|
426
|
+
|
|
427
|
+
Read all files in the `docs/` folder to understand the current template structure.
|
|
428
|
+
Each file has front matter with a title and a placeholder heading.
|
|
429
|
+
|
|
430
|
+
### Step 2: Read from Knowledge Index (REPLACES manual codebase scan)
|
|
431
|
+
|
|
432
|
+
Instead of manually scanning the codebase, use the pre-built index:
|
|
433
|
+
|
|
434
|
+
1. **Ensure index exists**: Run `diary index` if not already run
|
|
435
|
+
```bash
|
|
436
|
+
python -m diary index
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
2. **Read the knowledge database**: Query `docs/.index/knowledge.db` at the workspace root for:
|
|
440
|
+
- **Technology stack**: Search `files` table for config files (package.json, pyproject.toml, etc.)
|
|
441
|
+
- **Symbols/types**: Query `symbols` table grouped by `type` and `file_id`
|
|
442
|
+
- **Available modules**: Query `symbols` where `parent IS NULL` grouped by `file_id`
|
|
443
|
+
- **API endpoints**: Not directly indexed — still search for route definitions in source files
|
|
444
|
+
- **Database schemas**: Not directly indexed — check for ORM models and migrations
|
|
445
|
+
- **Documentation coverage**: Query `relations` table for doc-to-symbol links
|
|
446
|
+
|
|
447
|
+
Example queries:
|
|
448
|
+
```sql
|
|
449
|
+
-- Get all files by language
|
|
450
|
+
SELECT language, COUNT(*) as count FROM files GROUP BY language ORDER BY count DESC;
|
|
451
|
+
|
|
452
|
+
-- Get all top-level symbols (classes, interfaces)
|
|
453
|
+
SELECT name, type, fqn FROM symbols WHERE parent IS NULL;
|
|
454
|
+
|
|
455
|
+
-- Get undocumented symbols
|
|
456
|
+
SELECT s.name, s.type, f.rel_path FROM symbols s
|
|
457
|
+
JOIN files f ON s.file_id = f.id
|
|
458
|
+
WHERE s.id NOT IN (SELECT symbol_id FROM relations);
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
3. **Fall back to manual scan** for:
|
|
462
|
+
- API routes (Express routes, Flask blueprints, etc.)
|
|
463
|
+
- Business process details not captured by symbol extraction
|
|
464
|
+
- Configuration values and environment variables
|
|
465
|
+
|
|
466
|
+
### Step 3: Ask Clarifying Questions (IMPORTANT)
|
|
467
|
+
|
|
468
|
+
**SEBELUM menulis dokumentasi, WAJIB mengumpulkan informasi yang ambigu atau tidak tersedia di codebase.**
|
|
469
|
+
|
|
470
|
+
Gunakan tool `{tool_name}` untuk bertanya kepada user. Kumpulkan informasi berikut:
|
|
471
|
+
|
|
472
|
+
**Business Context:**
|
|
473
|
+
- Apa nama lengkap proyek dan deskripsi resmi?
|
|
474
|
+
- Siapa target pengguna utama (end-user, admin, developer)?
|
|
475
|
+
- Apa business process utama yang dijalankan sistem ini?
|
|
476
|
+
- Apa trigger/awal mula dari setiap business flow?
|
|
477
|
+
|
|
478
|
+
**Functional Requirements:**
|
|
479
|
+
- Fitur utama apa saja yang belum terlihat dari kode?
|
|
480
|
+
- Apa use case yang belum terdokumentasi?
|
|
481
|
+
- Apa edge case atau special scenario yang perlu dicatat?
|
|
482
|
+
|
|
483
|
+
**Non-Functional Requirements:**
|
|
484
|
+
- Apa target SLA untuk uptime dan response time?
|
|
485
|
+
- Apa requirement untuk scalability (expected user count, data volume)?
|
|
486
|
+
- Apa requirement untuk security compliance (SOC2, GDPR, dll)?
|
|
487
|
+
|
|
488
|
+
**Integration:**
|
|
489
|
+
- Sistem eksternal apa saja yang terintegrasi?
|
|
490
|
+
- Apa protocol yang digunakan (REST, gRPC, Message Queue)?
|
|
491
|
+
- Apa flow integrasi antar sistem?
|
|
492
|
+
|
|
493
|
+
**Deployment:**
|
|
494
|
+
- Berapa environment yang digunakan (dev, staging, production)?
|
|
495
|
+
- Apa infrastruktur yang digunakan (cloud provider, on-premise)?
|
|
496
|
+
- Apa CI/CD pipeline yang digunakan?
|
|
497
|
+
|
|
498
|
+
**Risks:**
|
|
499
|
+
- Apa known technical risks yang perlu didokumentasikan?
|
|
500
|
+
- Apa dependencies kritis yang perlu dihighlight?
|
|
501
|
+
|
|
502
|
+
**PENTING:**
|
|
503
|
+
- Jika informasi TIDAK tersedia di codebase dan user TIDAK memberikan jawaban,
|
|
504
|
+
gunakan placeholder `[ASSUMED: ...]` dan catat asumsi di dokumentasi.
|
|
505
|
+
- Jika user menjawab, gunakan jawaban tersebut sebagai sumber utama.
|
|
506
|
+
- Jangan berhalusinasi — lebih baik bertanya daripada menebak.
|
|
507
|
+
|
|
508
|
+
### Step 4: Generate Content for Each DIARY File
|
|
509
|
+
|
|
510
|
+
For each documentation file, generate appropriate content based on the codebase analysis.
|
|
511
|
+
|
|
512
|
+
#### docs/index.md
|
|
513
|
+
|
|
514
|
+
Update with:
|
|
515
|
+
- Project name and description (from package.json description, pyproject.toml, or README)
|
|
516
|
+
- Brief overview of what the project does
|
|
517
|
+
- Link to objectives and key documentation sections
|
|
518
|
+
|
|
519
|
+
#### docs/objectives.md
|
|
520
|
+
|
|
521
|
+
Generate project objectives based on what the code does:
|
|
522
|
+
- Primary objective (what problem does this project solve?)
|
|
523
|
+
- Key goals (performance, scalability, usability, etc.)
|
|
524
|
+
- Target users/audience
|
|
525
|
+
- Success metrics if identifiable
|
|
526
|
+
|
|
527
|
+
#### docs/structure/index.md
|
|
528
|
+
|
|
529
|
+
Update with project-specific writing guidelines:
|
|
530
|
+
- Link to DIARY documentation standards
|
|
531
|
+
- Reference to the project's documentation conventions
|
|
532
|
+
|
|
533
|
+
#### docs/techdocs/index.md (Technical Documentation Overview)
|
|
534
|
+
|
|
535
|
+
Update with:
|
|
536
|
+
- Brief description of the technical documentation section
|
|
537
|
+
- Tech stack summary (language, framework, database)
|
|
538
|
+
- List of available technical docs with links
|
|
539
|
+
- Kontak tim (placeholder names)
|
|
540
|
+
|
|
541
|
+
#### docs/techdocs/architecture.md
|
|
542
|
+
|
|
543
|
+
Generate architecture overview following the 7 analysis views:
|
|
544
|
+
|
|
545
|
+
**System Overview:**
|
|
546
|
+
- What the application does, its purpose
|
|
547
|
+
- Target users and use cases
|
|
548
|
+
|
|
549
|
+
**Tech Stack:**
|
|
550
|
+
| Komponen | Teknologi | Versi | Keterangan |
|
|
551
|
+
|----------|-----------|-------|------------|
|
|
552
|
+
| Frontend | ... | ... | ... |
|
|
553
|
+
| Backend | ... | ... | ... |
|
|
554
|
+
| Database | ... | ... | ... |
|
|
555
|
+
|
|
556
|
+
**Project Structure:**
|
|
557
|
+
- Directory tree with explanations
|
|
558
|
+
|
|
559
|
+
**Architecture Diagram:**
|
|
560
|
+
- Mermaid flowchart TD with subgraph grouping
|
|
561
|
+
- Show Presentation, Application, Integration, and Data layers
|
|
562
|
+
- Max 8-10 nodes per subgraph
|
|
563
|
+
- Use consistent styling
|
|
564
|
+
|
|
565
|
+
**Data Flow:**
|
|
566
|
+
- Sequence diagram for key business processes
|
|
567
|
+
|
|
568
|
+
**Integration Points:**
|
|
569
|
+
- List all external system integrations
|
|
570
|
+
- Protocol, direction, purpose
|
|
571
|
+
|
|
572
|
+
**Security Architecture:**
|
|
573
|
+
- Authentication mechanism
|
|
574
|
+
- Authorization model
|
|
575
|
+
- Data protection measures
|
|
576
|
+
|
|
577
|
+
#### docs/techdocs/api-contracts.md
|
|
578
|
+
|
|
579
|
+
If API routes/endpoints are found, for EACH endpoint document:
|
|
580
|
+
|
|
581
|
+
| Field | Description |
|
|
582
|
+
|-------|-------------|
|
|
583
|
+
| Purpose | What this endpoint does |
|
|
584
|
+
| Endpoint | URL path |
|
|
585
|
+
| Method | GET/POST/PUT/DELETE |
|
|
586
|
+
| Request Structure | Headers, body, params |
|
|
587
|
+
| Response Structure | Success and error responses |
|
|
588
|
+
| Validation Rules | Input validation requirements |
|
|
589
|
+
| Error Handling | Error codes and messages |
|
|
590
|
+
| Security | Auth requirements, rate limiting |
|
|
591
|
+
|
|
592
|
+
Provide request/response examples with JSON payloads.
|
|
593
|
+
Include error code reference table.
|
|
594
|
+
|
|
595
|
+
If no API found, note that this is a non-API project and document any public interfaces.
|
|
596
|
+
|
|
597
|
+
#### docs/techdocs/deployment.md
|
|
598
|
+
|
|
599
|
+
Generate deployment flow documentation:
|
|
600
|
+
- Deployment environments (development, staging, production)
|
|
601
|
+
- CI/CD pipeline overview (if .gitlab-ci.yml or similar found)
|
|
602
|
+
- Deployment steps
|
|
603
|
+
- Environment variables required
|
|
604
|
+
- Rollback procedures
|
|
605
|
+
|
|
606
|
+
#### docs/techdocs/adr.md
|
|
607
|
+
|
|
608
|
+
Generate Architecture Decision Record:
|
|
609
|
+
- ADR format with status, context, decision, consequences
|
|
610
|
+
- Add initial ADR entries for major architectural choices found in code
|
|
611
|
+
|
|
612
|
+
#### docs/techdocs/development-guide.md
|
|
613
|
+
|
|
614
|
+
Generate development guide:
|
|
615
|
+
- **Prerequisites**: Required tools and versions (from dependency files)
|
|
616
|
+
- **Setup instructions**: Step-by-step local development setup
|
|
617
|
+
- **Project structure**: Explanation of key directories and files
|
|
618
|
+
- **Coding standards**: Based on existing code patterns (linting config, formatting, etc.)
|
|
619
|
+
- **Testing**: How to run tests (from package.json scripts, Makefile, etc.)
|
|
620
|
+
|
|
621
|
+
#### docs/product/index.md (Product Documentation Overview)
|
|
622
|
+
|
|
623
|
+
Update with:
|
|
624
|
+
- Product description (what the product does for users)
|
|
625
|
+
- Key features list
|
|
626
|
+
- Target audience
|
|
627
|
+
- Current version info
|
|
628
|
+
|
|
629
|
+
#### docs/product/user-guide.md
|
|
630
|
+
|
|
631
|
+
Generate user guide with use case format:
|
|
632
|
+
|
|
633
|
+
For each major use case:
|
|
634
|
+
| Field | Description |
|
|
635
|
+
|-------|-------------|
|
|
636
|
+
| Use Case Name | Name of the use case |
|
|
637
|
+
| Objective | What the user achieves |
|
|
638
|
+
| Actor | Who performs this |
|
|
639
|
+
| Preconditions | What must be true before |
|
|
640
|
+
| Main Flow | Step-by-step process |
|
|
641
|
+
| Alternative Flow | Other ways to accomplish |
|
|
642
|
+
| Error Flow | What happens on error |
|
|
643
|
+
| Post Conditions | What is true after |
|
|
644
|
+
|
|
645
|
+
Include business flow diagrams (Mermaid sequence diagrams).
|
|
646
|
+
|
|
647
|
+
#### docs/product/modules.md
|
|
648
|
+
|
|
649
|
+
List all modules/components found in the codebase:
|
|
650
|
+
| Module | Purpose | Key Files | Dependencies |
|
|
651
|
+
|--------|---------|-----------|--------------|
|
|
652
|
+
| ... | ... | ... | ... |
|
|
653
|
+
|
|
654
|
+
Include module relationship diagram if complex.
|
|
655
|
+
|
|
656
|
+
#### docs/ops-governance/index.md (Ops & Governance Overview)
|
|
657
|
+
|
|
658
|
+
Update with:
|
|
659
|
+
| Parameter | Target SLA | Keterangan |
|
|
660
|
+
|-----------|-----------|------------|
|
|
661
|
+
| Uptime | 99.5% per bulan | ... |
|
|
662
|
+
| Response Time | < 500ms (P95) | ... |
|
|
663
|
+
| RTO | < 4 jam | ... |
|
|
664
|
+
| RPO | < 1 jam | ... |
|
|
665
|
+
|
|
666
|
+
- Maintenance schedule
|
|
667
|
+
- Escalation contacts
|
|
668
|
+
|
|
669
|
+
#### docs/ops-governance/runbooks.md
|
|
670
|
+
|
|
671
|
+
Generate operational runbooks for each common scenario:
|
|
672
|
+
- Incident response procedures
|
|
673
|
+
- Monitoring and alerting setup
|
|
674
|
+
- Backup/restore procedures
|
|
675
|
+
- Scaling procedures
|
|
676
|
+
- Health check procedures
|
|
677
|
+
|
|
678
|
+
Include severity level table:
|
|
679
|
+
| Severity | Definisi | Response Time | Resolusi Target |
|
|
680
|
+
|----------|----------|---------------|-----------------|
|
|
681
|
+
| Critical | ... | ... | ... |
|
|
682
|
+
| High | ... | ... | ... |
|
|
683
|
+
| Medium | ... | ... | ... |
|
|
684
|
+
| Low | ... | ... | ... |
|
|
685
|
+
|
|
686
|
+
#### docs/ops-governance/security.md
|
|
687
|
+
|
|
688
|
+
Generate security documentation covering:
|
|
689
|
+
| Aspect | Implementation |
|
|
690
|
+
|--------|---------------|
|
|
691
|
+
| Authentication | JWT/OAuth/etc. |
|
|
692
|
+
| Authorization | RBAC/etc. |
|
|
693
|
+
| Data Protection | Encryption at rest/transit |
|
|
694
|
+
| Audit Trail | Logging mechanism |
|
|
695
|
+
| Rate Limiting | Configuration |
|
|
696
|
+
| API Security | CORS, CSP, etc. |
|
|
697
|
+
|
|
698
|
+
Include security checklist and compliance considerations.
|
|
699
|
+
|
|
700
|
+
#### docs/knowledge-base/index.md (Knowledge Base Overview)
|
|
701
|
+
|
|
702
|
+
Update with:
|
|
703
|
+
- Purpose of the knowledge base
|
|
704
|
+
- How to contribute
|
|
705
|
+
- Categories of information available
|
|
706
|
+
|
|
707
|
+
#### docs/knowledge-base/faq.md
|
|
708
|
+
|
|
709
|
+
Generate common questions based on code patterns:
|
|
710
|
+
- How to set up the project?
|
|
711
|
+
- How to run tests?
|
|
712
|
+
- How to deploy?
|
|
713
|
+
- Common error messages and solutions
|
|
714
|
+
- Configuration options
|
|
715
|
+
|
|
716
|
+
#### docs/knowledge-base/troubleshooting.md
|
|
717
|
+
|
|
718
|
+
Generate troubleshooting guide:
|
|
719
|
+
- Common issues and their solutions
|
|
720
|
+
- Error message reference
|
|
721
|
+
- Debug steps
|
|
722
|
+
- Log analysis guide
|
|
723
|
+
|
|
724
|
+
### Step 4: Apply DIARY Guidelines
|
|
725
|
+
|
|
726
|
+
ALL generated content MUST follow these rules:
|
|
727
|
+
|
|
728
|
+
1. **Language**: Use **Bahasa Indonesia** as the primary language for prose
|
|
729
|
+
2. **Technical terms**: Keep in English without translation: `deployment`, `pipeline`,
|
|
730
|
+
`endpoint`, `payload`, `commit`, `merge request`, `branch`, `container`, `middleware`,
|
|
731
|
+
`repository`, `service`, `database`, `cache`, `queue`, etc.
|
|
732
|
+
3. **Markdown format**:
|
|
733
|
+
- One H1 per file as the page title
|
|
734
|
+
- Hierarchical headings (H1 > H2 > H3)
|
|
735
|
+
- Front matter with `title` field
|
|
736
|
+
- Code blocks with language identifiers
|
|
737
|
+
- Tables for structured data
|
|
738
|
+
- Mermaid diagrams for architecture/flow visualization
|
|
739
|
+
4. **Admonitions**: Use for important notes:
|
|
740
|
+
```markdown
|
|
741
|
+
!!! note "Catatan"
|
|
742
|
+
Informasi tambahan.
|
|
743
|
+
|
|
744
|
+
!!! warning "Perhatian"
|
|
745
|
+
Peringatan penting.
|
|
746
|
+
|
|
747
|
+
!!! tip "Tips"
|
|
748
|
+
Saran berguna.
|
|
749
|
+
```
|
|
750
|
+
5. **Do NOT** include sensitive information (passwords, API keys, internal IPs)
|
|
751
|
+
6. **Use placeholders** like `YOUR_API_KEY_HERE` for sensitive values
|
|
752
|
+
7. **Diagrams**: Follow Mermaid rules above — professional, readable, grouped with subgraph
|
|
753
|
+
|
|
754
|
+
### Step 5: Non-Functional Requirements
|
|
755
|
+
|
|
756
|
+
Selalu identifikasi dan dokumentasikan:
|
|
757
|
+
- **Availability** — Uptime target, redundancy
|
|
758
|
+
- **Reliability** — Error rates, retry mechanisms
|
|
759
|
+
- **Scalability** — Horizontal/vertical scaling considerations
|
|
760
|
+
- **Performance** — Response time targets, throughput
|
|
761
|
+
- **Maintainability** — Code quality, documentation coverage
|
|
762
|
+
- **Observability** — Logging, monitoring, alerting
|
|
763
|
+
- **Disaster Recovery** — Backup, restore, failover
|
|
764
|
+
|
|
765
|
+
### Step 6: Risk Assessment
|
|
766
|
+
|
|
767
|
+
Dokumentasikan risiko yang ditemukan:
|
|
768
|
+
| Risk Type | Description | Impact | Mitigation |
|
|
769
|
+
|-----------|-------------|--------|------------|
|
|
770
|
+
| Technical | ... | ... | ... |
|
|
771
|
+
| Business | ... | ... | ... |
|
|
772
|
+
| Operational | ... | ... | ... |
|
|
773
|
+
|
|
774
|
+
### Step 7: Write the Files
|
|
775
|
+
|
|
776
|
+
After generating all content, write each file to the appropriate path in `docs/`.
|
|
777
|
+
Preserve existing front matter titles but update the content.
|
|
778
|
+
|
|
779
|
+
### Step 8: Generate Deliverables
|
|
780
|
+
|
|
781
|
+
Pastikan dokumentasi yang dihasilkan mencakup:
|
|
782
|
+
1. Executive Summary
|
|
783
|
+
2. Business Flow
|
|
784
|
+
3. Use Cases
|
|
785
|
+
4. Functional Requirements
|
|
786
|
+
5. Non Functional Requirements
|
|
787
|
+
6. Architecture Diagram
|
|
788
|
+
7. Integration Diagram
|
|
789
|
+
8. Data Model
|
|
790
|
+
9. API Specification
|
|
791
|
+
10. Security Consideration
|
|
792
|
+
11. Deployment Architecture
|
|
793
|
+
12. Risks & Assumptions
|
|
794
|
+
|
|
795
|
+
Output harus menyerupai dokumentasi proyek enterprise yang siap masuk Confluence,
|
|
796
|
+
Git Repository, atau Technical Design Document.
|
|
797
|
+
|
|
798
|
+
Report a summary of all files updated when complete.
|
|
799
|
+
"""
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
def generate_skill_content(is_opencode: bool = False) -> str:
|
|
803
|
+
"""Return the skill file content for diary-generate-content."""
|
|
804
|
+
heading = "diary-generate-content" if is_opencode else "/diary-generate-content"
|
|
805
|
+
tool_name = "question" if is_opencode else "AskUserQuestion"
|
|
806
|
+
return SKILL_CONTENT.format(heading=heading, tool_name=tool_name)
|
|
807
|
+
|
|
808
|
+
|
|
809
|
+
def create_structure(project_name: str, base_path: Path, force: bool = False) -> None:
|
|
810
|
+
"""Create the DIARY documentation folder structure with all template files."""
|
|
811
|
+
docs = base_path / "docs"
|
|
812
|
+
folders = {
|
|
813
|
+
docs: {
|
|
814
|
+
"index": (project_name, project_name),
|
|
815
|
+
"files": [("objectives.md", "objectives", "Tujuan")],
|
|
816
|
+
},
|
|
817
|
+
docs / "structure": {
|
|
818
|
+
"index": ("structure", "Panduan Umum Menulis Docs"),
|
|
819
|
+
"files": [],
|
|
820
|
+
},
|
|
821
|
+
docs / "techdocs": {
|
|
822
|
+
"index": ("techdocs", "Technical Documentation - Overview"),
|
|
823
|
+
"files": [
|
|
824
|
+
("architecture.md", "architecture", "Arsitektur Sistem"),
|
|
825
|
+
("api-contracts.md", "api-contracts", "API Contracts"),
|
|
826
|
+
("deployment.md", "deployment", "Deployment Flow"),
|
|
827
|
+
("adr.md", "adr", "Architecture Decision Record"),
|
|
828
|
+
("development-guide.md", "development-guide", "Development Guide"),
|
|
829
|
+
],
|
|
830
|
+
},
|
|
831
|
+
docs / "product": {
|
|
832
|
+
"index": ("product", "Product Documentation - Overview"),
|
|
833
|
+
"files": [
|
|
834
|
+
("user-guide.md", "user-guide", "User Guide"),
|
|
835
|
+
("modules.md", "modules", "Modules"),
|
|
836
|
+
],
|
|
837
|
+
},
|
|
838
|
+
docs / "ops-governance": {
|
|
839
|
+
"index": ("ops-governance", "Ops & Governance - Overview"),
|
|
840
|
+
"files": [
|
|
841
|
+
("runbooks.md", "runbooks", "Runbooks"),
|
|
842
|
+
("security.md", "security", "Security Compliance"),
|
|
843
|
+
],
|
|
844
|
+
},
|
|
845
|
+
docs / "knowledge-base": {
|
|
846
|
+
"index": ("knowledge-base", "Knowledge Base - Overview"),
|
|
847
|
+
"files": [
|
|
848
|
+
("faq.md", "faq", "FAQ"),
|
|
849
|
+
("troubleshooting.md", "troubleshooting", "Troubleshooting"),
|
|
850
|
+
],
|
|
851
|
+
},
|
|
852
|
+
}
|
|
853
|
+
for folder, config in folders.items():
|
|
854
|
+
folder.mkdir(parents=True, exist_ok=True)
|
|
855
|
+
index_title, index_heading = config["index"]
|
|
856
|
+
index = folder / "index.md"
|
|
857
|
+
if force or not index.exists():
|
|
858
|
+
content = aimb_wrap_body(f"---\ntitle: {index_title}\n---\n\n# {index_heading}\n", "index.md")
|
|
859
|
+
index.write_text(content, encoding="utf-8")
|
|
860
|
+
for filename, title, heading in config["files"]:
|
|
861
|
+
f = folder / filename
|
|
862
|
+
if force or not f.exists():
|
|
863
|
+
content = aimb_wrap_body(f"---\ntitle: {title}\n---\n\n# {heading}\n", filename)
|
|
864
|
+
f.write_text(content, encoding="utf-8")
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
def main():
|
|
868
|
+
try:
|
|
869
|
+
banner = Text(BANNER, style="bold orange1")
|
|
870
|
+
console.print(banner)
|
|
871
|
+
except (UnicodeEncodeError, UnicodeError):
|
|
872
|
+
pass # Some terminals (e.g. Windows cp1252) cannot render Unicode box-drawing characters
|
|
873
|
+
|
|
874
|
+
parser = argparse.ArgumentParser(prog="diary-docs", description="DIARY documentation scaffolder")
|
|
875
|
+
parser.add_argument("--version", action="version", version="%(prog)s 0.1.0")
|
|
876
|
+
|
|
877
|
+
subparsers = parser.add_subparsers(dest="command")
|
|
878
|
+
init_parser = subparsers.add_parser("init", help="Initialize a new DIARY documentation project")
|
|
879
|
+
init_parser.add_argument("-f", "--force", action="store_true", help="Overwrite existing files")
|
|
880
|
+
|
|
881
|
+
index_parser = subparsers.add_parser("index", help="Index workspace for knowledge retrieval")
|
|
882
|
+
index_parser.add_argument("--report", "-r", action="store_true", help="Generate coverage report after indexing")
|
|
883
|
+
index_parser.add_argument("--db-path", type=str, help="Custom database path (default: docs/.index/knowledge.db)")
|
|
884
|
+
|
|
885
|
+
sync_parser = subparsers.add_parser("sync", help="Sync documentation with code changes")
|
|
886
|
+
sync_parser.add_argument("--dry-run", "-n", action="store_true", help="Preview changes without applying")
|
|
887
|
+
sync_parser.add_argument("--branch", "-b", type=str, default="", help="Override branch detection")
|
|
888
|
+
sync_parser.add_argument("--force", "-f", action="store_true", help="Skip conflict warnings")
|
|
889
|
+
sync_parser.add_argument("--output", "-o", type=str, help="Write JSON report to file")
|
|
890
|
+
|
|
891
|
+
try:
|
|
892
|
+
args = parser.parse_args()
|
|
893
|
+
except SystemExit as e:
|
|
894
|
+
sys.exit(e.code)
|
|
895
|
+
|
|
896
|
+
if args.command is None:
|
|
897
|
+
parser.print_help()
|
|
898
|
+
sys.exit(1)
|
|
899
|
+
|
|
900
|
+
if args.command == "init":
|
|
901
|
+
try:
|
|
902
|
+
name = input("Project name: ").strip()
|
|
903
|
+
except KeyboardInterrupt:
|
|
904
|
+
print()
|
|
905
|
+
sys.exit(0)
|
|
906
|
+
|
|
907
|
+
if not name:
|
|
908
|
+
print("Error: Project name cannot be empty", file=sys.stderr)
|
|
909
|
+
sys.exit(1)
|
|
910
|
+
|
|
911
|
+
if not os.access(Path.cwd(), os.W_OK):
|
|
912
|
+
print("Error: No write permission in current directory", file=sys.stderr)
|
|
913
|
+
sys.exit(1)
|
|
914
|
+
|
|
915
|
+
try:
|
|
916
|
+
create_structure(name, Path.cwd(), force=args.force)
|
|
917
|
+
|
|
918
|
+
mkdocs_path = Path.cwd() / "mkdocs.yml"
|
|
919
|
+
if args.force or not mkdocs_path.exists():
|
|
920
|
+
mkdocs_path.write_text(
|
|
921
|
+
MKDOCS_TEMPLATE.format(project_name=name), encoding="utf-8"
|
|
922
|
+
)
|
|
923
|
+
|
|
924
|
+
catalog_path = Path.cwd() / "catalog-info.yaml"
|
|
925
|
+
if args.force or not catalog_path.exists():
|
|
926
|
+
catalog_path.write_text(
|
|
927
|
+
CATALOG_TEMPLATE.format(project_name=name, project_title=name.title()),
|
|
928
|
+
encoding="utf-8",
|
|
929
|
+
)
|
|
930
|
+
|
|
931
|
+
try:
|
|
932
|
+
if sys.stdin.isatty():
|
|
933
|
+
choice = inquirer.select(
|
|
934
|
+
message="Skill structure?",
|
|
935
|
+
choices=["Claude Code", "OpenCode"],
|
|
936
|
+
default="Claude Code",
|
|
937
|
+
).execute()
|
|
938
|
+
else:
|
|
939
|
+
choice = "Claude Code"
|
|
940
|
+
choice = "1" if choice == "Claude Code" else "2"
|
|
941
|
+
except (EOFError, KeyboardInterrupt, SystemExit):
|
|
942
|
+
print()
|
|
943
|
+
choice = "1"
|
|
944
|
+
|
|
945
|
+
if choice == "1":
|
|
946
|
+
skill_dir = Path.cwd() / ".claude" / "commands"
|
|
947
|
+
elif choice == "2":
|
|
948
|
+
skill_dir = Path.cwd() / ".opencode" / "commands"
|
|
949
|
+
else:
|
|
950
|
+
print("Error: Invalid choice. Use 1 for Claude Code or 2 for OpenCode.", file=sys.stderr)
|
|
951
|
+
sys.exit(1)
|
|
952
|
+
|
|
953
|
+
skill_dir.mkdir(parents=True, exist_ok=True)
|
|
954
|
+
skill_file = skill_dir / "diary-generate-content.md"
|
|
955
|
+
skill_file.write_text(
|
|
956
|
+
generate_skill_content(is_opencode=(choice == "2")),
|
|
957
|
+
encoding="utf-8",
|
|
958
|
+
)
|
|
959
|
+
sync_file = skill_dir / "diary-sync.md"
|
|
960
|
+
sync_file.write_text(SYNC_CONTENT, encoding="utf-8")
|
|
961
|
+
|
|
962
|
+
print(f"DIARY structure created for '{name}'")
|
|
963
|
+
except Exception as e:
|
|
964
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
965
|
+
sys.exit(1)
|
|
966
|
+
|
|
967
|
+
if args.command == "index":
|
|
968
|
+
db_path = Path(args.db_path) if args.db_path else None
|
|
969
|
+
db = run_index(Path.cwd(), db_path=db_path)
|
|
970
|
+
if args.report:
|
|
971
|
+
generate_report(db, Path.cwd())
|
|
972
|
+
db.close()
|
|
973
|
+
sys.exit(0)
|
|
974
|
+
|
|
975
|
+
if args.command == "sync":
|
|
976
|
+
config = SyncConfig(
|
|
977
|
+
workspace_path=Path.cwd(),
|
|
978
|
+
branch_override=args.branch,
|
|
979
|
+
dry_run=args.dry_run,
|
|
980
|
+
force=args.force,
|
|
981
|
+
)
|
|
982
|
+
result = run_sync(config)
|
|
983
|
+
|
|
984
|
+
if result.errors:
|
|
985
|
+
for err in result.errors:
|
|
986
|
+
print(err, file=sys.stderr)
|
|
987
|
+
|
|
988
|
+
if result.report is not None:
|
|
989
|
+
json_output = serialize_report(result.report)
|
|
990
|
+
if args.output:
|
|
991
|
+
try:
|
|
992
|
+
Path(args.output).write_text(json_output, encoding="utf-8")
|
|
993
|
+
except OSError as e:
|
|
994
|
+
print(f"Error: Cannot write to {args.output}: {e}", file=sys.stderr)
|
|
995
|
+
sys.exit(1)
|
|
996
|
+
else:
|
|
997
|
+
print(json_output)
|
|
998
|
+
|
|
999
|
+
sys.exit(0 if result.success else 1)
|