hanoman 0.1.16 → 0.1.18

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.
@@ -168,12 +168,52 @@ dan tak memakai agent token.
168
168
  | `GET /api/specs/:id/review` | `backlog:read` | diff hasil kerja sesi. |
169
169
  | `GET /api/projects/:id/docs` | `docs:read` | index Source of Truth project. |
170
170
  | `GET /api/projects/:id/docs/<path>` | `docs:read` | isi satu dokumen. |
171
+ | `GET /api/projects/:id/changelog` | `docs:read` | changelog yang sudah dibangkitkan (paginated). |
172
+ | `POST /api/projects/:id/changelog` | `docs:write` | bangkitkan changelog baru — bentuknya di **§6a**. |
171
173
  | `GET /api/terminal/sessions` | `sessions:read` | sesi yang sedang hidup. |
172
174
  | `GET /api/notifications` | `notifications:read` | notifikasi. |
173
175
  | `GET /api/tickets` | `support:read` | tiket Help Center. |
174
176
  | `GET /api/lead/decisions` | `lead:read` | jejak keputusan hanoman-lead. |
175
177
  | `POST /api/lead/decisions` | `lead:write` | minta putusan — baca **§8** dan **§11** dulu. |
176
178
 
179
+ ## 6a. Changelog per project
180
+
181
+ Ringkasan perubahan **berorientasi pemakai** — bukan daftar commit. Tiga mode, satu endpoint;
182
+ `mode` menentukan field lainnya:
183
+
184
+ ```bash
185
+ # 1) backlog yang selesai di rentang tanggal (dua field opsional → 30 hari terakhir)
186
+ curl -sS -X POST "$HANOMAN_HOST/api/projects/<id>/changelog" \
187
+ -H "Authorization: Bearer $HANOMAN_AGENT_TOKEN" -H 'Content-Type: application/json' \
188
+ -d '{"mode":"backlog","from":"2026-07-01","to":"2026-07-31"}'
189
+
190
+ # 2) rentang commit di repo project
191
+ -d '{"mode":"commit","fromSha":"4f2a1c9","toSha":"HEAD"}'
192
+
193
+ # 3) versi/tag rilis (fromTag opsional → sejak versi sebelumnya)
194
+ -d '{"mode":"version","toTag":"v1.2.0"}'
195
+ ```
196
+
197
+ Jawaban **201** berisi `body` (markdown siap pakai), `title`, `itemCount`, `generator`, dan
198
+ `warning`. Ambil ulang atau unduh kapan saja:
199
+
200
+ ```bash
201
+ curl -sS "$HANOMAN_HOST/api/projects/<id>/changelog/<cid>?download=md" \
202
+ -H "Authorization: Bearer $HANOMAN_AGENT_TOKEN"
203
+ ```
204
+
205
+ Tiga hal yang perlu kamu tahu sebelum memanggilnya:
206
+
207
+ - **Panggil `GET /api/projects/:id/changelog/sources` dulu.** Ia memberi tag yang tersedia, HEAD
208
+ singkat, rentang default, dan — bila repo belum ditautkan di mesin itu atau belum punya tag — satu
209
+ `reason` yang menjelaskan sebabnya. Ia menjawab **200**, bukan galat, jadi jangan perlakukan
210
+ `reason` sebagai kegagalan.
211
+ - **422 berarti permintaanmu sah tapi tak ada isinya** (rentang kosong, repo tanpa tag, revisi tak
212
+ dikenal) — pesannya bisa langsung diteruskan ke manusia. **400** berarti bentuknya salah
213
+ (mis. `from` lebih baru dari `to`).
214
+ - **`generator:"fallback"` bukan kegagalan.** Artinya narasi otomatis tak tersedia dan yang kamu
215
+ terima adalah draf ringkas deterministik; alasannya ada di `warning`.
216
+
177
217
  ## 7. `POST /api/specs` — bentuk payload per `source`
178
218
 
179
219
  `source` dan bentuk `payload` **saling mengikat**. Salah pasang → **400**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hanoman",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "description": "Orchestrator + dashboard workflow docs-driven untuk sesi Claude Code / Codex",
5
5
  "type": "module",
6
6
  "repository": {
@@ -0,0 +1,16 @@
1
+ -- SPEC-516 · ADR-0105 · stempel selesai backlog sebagai kolom.
2
+ --
3
+ -- Ditulis tangan (bukan `migrate dev`): worktree tetangga membuat `migrate dev` me-reset DB saat
4
+ -- ada drift. ADITIF murni — satu kolom NULLABLE tanpa default, tak ada tabel diredefinisi.
5
+ -- Larangan SQLite atas `ADD COLUMN … DEFAULT <non-konstan>` (lihat migration SPEC-408) tak
6
+ -- berlaku karena tak ada default sama sekali.
7
+ ALTER TABLE "Spec" ADD COLUMN "doneAt" DATETIME;
8
+
9
+ -- Backfill sekali-jalan dari stempel yang SUDAH ada: `Notification` ber-key `done:<specId>`
10
+ -- ditulis `recordCompletion` tepat pada transisi ke `done` sejak SPEC-180, di ketiga jalur
11
+ -- persist (dasar yang sama dipakai sweep auto-merge ADR-0103). Item yang selesai sebelum
12
+ -- SPEC-180 — atau yang notifikasinya dihapus operator — tetap NULL; itu keadaan sah yang
13
+ -- dilaporkan sebagai catatan di hasil changelog, bukan disamarkan.
14
+ UPDATE "Spec" SET "doneAt" = (
15
+ SELECT n."createdAt" FROM "Notification" n WHERE n."key" = 'done:' || "Spec"."id"
16
+ ) WHERE "doneAt" IS NULL;
@@ -0,0 +1,21 @@
1
+ -- SPEC-516 · ADR-0105 · changelog naratif per project.
2
+ --
3
+ -- Ditulis tangan (bukan `migrate dev`). ADITIF murni — satu tabel baru, nol tabel diredefinisi,
4
+ -- nol baris disentuh. TANPA kolom `version`: tabel ini LOCAL-only dan tak pernah masuk
5
+ -- changefeed sync, persis alasan `LeadFlow` & `WebhookEndpoint`.
6
+ CREATE TABLE "Changelog" (
7
+ "id" TEXT NOT NULL PRIMARY KEY,
8
+ "projectId" TEXT NOT NULL,
9
+ "mode" TEXT NOT NULL,
10
+ "title" TEXT NOT NULL,
11
+ "params" JSONB NOT NULL,
12
+ "body" TEXT NOT NULL,
13
+ "generator" TEXT NOT NULL,
14
+ "warning" TEXT,
15
+ "itemCount" INTEGER NOT NULL DEFAULT 0,
16
+ "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
17
+ "updatedAt" DATETIME NOT NULL,
18
+ CONSTRAINT "Changelog_projectId_fkey" FOREIGN KEY ("projectId")
19
+ REFERENCES "Project" ("id") ON DELETE CASCADE ON UPDATE CASCADE
20
+ );
21
+ CREATE INDEX "Changelog_projectId_createdAt_idx" ON "Changelog"("projectId", "createdAt");
@@ -28,6 +28,7 @@ model Project {
28
28
  tickets Ticket[]
29
29
  customAgents CustomAgent[] // SPEC-450 · ADR-0094 · custom agent milik project ini
30
30
  githubIssues GithubIssue[] // SPEC-471 · ADR-0095 · cermin issue repo GitHub project ini
31
+ changelogs Changelog[] // SPEC-516 · ADR-0105 · changelog tersimpan project ini
31
32
  }
32
33
 
33
34
  model Spec {
@@ -51,6 +52,12 @@ model Spec {
51
52
  // sama dengan `baseSha` (services/session-launch.ts); jalur RESUME (ADR-0084) sengaja tidak
52
53
  // menimpanya — melanjutkan sesi bukan "mulai lagi". null = belum pernah dikerjakan.
53
54
  startedAt DateTime?
55
+ // SPEC-516 · ADR-0105 · kapan item PERTAMA kali masuk stage `done`. Ditulis HANYA di dalam
56
+ // `recordCompletion()` — satu-satunya fungsi yang sudah dipanggil oleh KETIGA jalur persist
57
+ // `done` (advanceStage, scheduler/reconcile, live-specs). Menyalin bookkeeping ini ke call
58
+ // site adalah kelas bug SPEC-431/448/475. Tulis-sekali: reopen lalu selesai lagi tak
59
+ // memindahkannya, cermin `startedAt` = mulai pertama (ADR-0090).
60
+ doneAt DateTime?
54
61
  // SPEC-447 · ADR-0093 · id spec lain yang harus SELESAI & commit-nya sudah ada di branch basis
55
62
  // sebelum item ini boleh diluncurkan. Array JSON of string; null/[] = tak bergantung apa pun.
56
63
  // Sengaja kolom, bukan tabel join: SQLite melarang scalar list, `Json` sudah dipakai `payload`,
@@ -64,6 +71,29 @@ model Spec {
64
71
  project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
65
72
  }
66
73
 
74
+ // SPEC-516 · ADR-0105 · changelog naratif per project yang sudah dibangkitkan.
75
+ //
76
+ // LOCAL-only: TANPA kolom `version`, jadi ia tak pernah masuk changefeed sync (cermin LeadFlow,
77
+ // WebhookEndpoint, dan Project.autoMerge). Dua dari tiga modenya diturunkan dari checkout git di
78
+ // MESIN INI, jadi barisnya fakta lokal; yang portabel adalah keluarannya, dan jalannya sudah ada
79
+ // — unduh .md.
80
+ model Changelog {
81
+ id String @id @default(cuid())
82
+ projectId String
83
+ mode String // "backlog" | "commit" | "version" (zChangelogMode di @hanoman/shared)
84
+ title String // judul di daftar: rentang tanggal / nama tag / rentang tag
85
+ params Json // parameter pembangkitan apa adanya (zChangelogRequest)
86
+ body String // markdown hasil akhir, sudah lewat scrubOutput
87
+ generator String // "agent" | "fallback"
88
+ warning String? // alasan fallback + catatan cakupan; null = mulus
89
+ itemCount Int @default(0)
90
+ createdAt DateTime @default(now())
91
+ updatedAt DateTime @updatedAt
92
+ project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
93
+
94
+ @@index([projectId, createdAt])
95
+ }
96
+
67
97
  // SPEC-450 · ADR-0094 · custom agent: persona yang bisa dipilih ulang & dibagi.
68
98
  // `projectId` null = GLOBAL (semua project); terisi = milik satu project, dan agen project
69
99
  // MENIMPA agen global bernama sama.