hanoman 0.1.50 → 0.1.51

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.1.50",
3
- "sha": "30fe53e3",
4
- "builtAt": "2026-08-20T04:25:22.099Z"
2
+ "version": "0.1.51",
3
+ "sha": "10136c9c",
4
+ "builtAt": "2026-08-20T11:59:29.467Z"
5
5
  }
package/dist/server.js CHANGED
@@ -40411,9 +40411,17 @@ async function __tick() {
40411
40411
  let msg;
40412
40412
  try {
40413
40413
  msg = await g.build();
40414
- } catch {
40414
+ } catch (e) {
40415
+ if (!g.failing) {
40416
+ g.failing = true;
40417
+ console.error("siar dashboard gagal membangun frame:", e);
40418
+ }
40415
40419
  continue;
40416
40420
  }
40421
+ if (g.failing) {
40422
+ g.failing = false;
40423
+ console.log(`siar dashboard pulih: ${msg.t}`);
40424
+ }
40417
40425
  const sig = JSON.stringify(msg);
40418
40426
  if (sig === g.last) continue;
40419
40427
  g.last = sig;
@@ -46935,7 +46943,9 @@ var RETENTION_DAYS = {
46935
46943
  newTickets: 180,
46936
46944
  sessions: 30,
46937
46945
  deliveries: 30,
46938
- sessionResults: 90
46946
+ sessionResults: 90,
46947
+ // SPEC-857 · ADR-0131 · change-feed sync. Lihat `pruneSyncFeed` untuk invarian yang menjaganya.
46948
+ syncFeed: 7
46939
46949
  };
46940
46950
  var before = (now, days) => new Date(now.getTime() - days * 864e5);
46941
46951
  async function runRetention(opts = {}, deps = {}) {
@@ -46945,9 +46955,11 @@ async function runRetention(opts = {}, deps = {}) {
46945
46955
  bytes: 0,
46946
46956
  failed: 0,
46947
46957
  orphans: 0,
46948
- dangling: 0
46958
+ dangling: 0,
46959
+ feedPruned: 0
46949
46960
  };
46950
46961
  await deleteExpired(report, opts, deps);
46962
+ report.feedPruned = await pruneSyncFeed(opts.now ?? /* @__PURE__ */ new Date(), opts.dryRun ?? false);
46951
46963
  const gc = await reconcileTranscripts({ dryRun: opts.dryRun });
46952
46964
  report.orphans = gc.orphans;
46953
46965
  report.dangling = gc.dangling;
@@ -47045,14 +47057,43 @@ async function deleteExpired(report, opts, deps) {
47045
47057
  if (remaining <= 0) break;
47046
47058
  }
47047
47059
  }
47060
+ async function pruneSyncFeed(now, dryRun = false) {
47061
+ const cutoff = before(now, RETENTION_DAYS.syncFeed);
47062
+ const groups = await prisma.syncLog.groupBy({
47063
+ by: ["entity", "recordId"],
47064
+ _count: { _all: true },
47065
+ _max: { seq: true }
47066
+ });
47067
+ let pruned = 0;
47068
+ for (const g of groups) {
47069
+ if (g._count._all <= 1) continue;
47070
+ const tip = g._max.seq;
47071
+ if (tip === null || tip === void 0) continue;
47072
+ const where = {
47073
+ entity: g.entity,
47074
+ recordId: g.recordId,
47075
+ seq: { lt: tip },
47076
+ // tersusul — puncaknya selalu selamat
47077
+ createdAt: { lt: cutoff }
47078
+ // dan sudah lewat jendela retensi
47079
+ };
47080
+ if (dryRun) {
47081
+ pruned += await prisma.syncLog.count({ where });
47082
+ continue;
47083
+ }
47084
+ const { count } = await prisma.syncLog.deleteMany({ where });
47085
+ pruned += count;
47086
+ }
47087
+ return pruned;
47088
+ }
47048
47089
  var timer8;
47049
47090
  function startRetentionSweep() {
47050
47091
  if (timer8) return;
47051
47092
  const sweep2 = () => {
47052
47093
  const holds = new Set((process.env.HANOMAN_RETENTION_HOLDS ?? "").split(",").map((v) => v.trim()).filter(Boolean));
47053
47094
  void runRetention({ holds }).then((report) => {
47054
- if (report.deleted || report.failed || report.orphans || report.dangling) {
47055
- console.log(`retention: ${report.deleted} dihapus, ${report.failed} gagal, ${report.orphans} transkrip yatim disapu, ${report.dangling} metadata menggantung dibersihkan`);
47095
+ if (report.deleted || report.failed || report.orphans || report.dangling || report.feedPruned) {
47096
+ console.log(`retention: ${report.deleted} dihapus, ${report.failed} gagal, ${report.orphans} transkrip yatim disapu, ${report.dangling} metadata menggantung dibersihkan, ${report.feedPruned} baris change-feed tersusul dipangkas`);
47056
47097
  }
47057
47098
  }).catch((error) => console.error("retention sweep:", error));
47058
47099
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hanoman",
3
- "version": "0.1.50",
3
+ "version": "0.1.51",
4
4
  "description": "Orchestrator + dashboard workflow docs-driven untuk sesi Claude Code / Codex",
5
5
  "type": "module",
6
6
  "repository": {